httpbin 是我练手的一个非常简单的小项目,功能就是:
- HTTP POST 请求 (
POST /
) 提交一个字符串,服务器返回一个 ID。 - HTTP GET 请求 (
GET /xxxx
),返回 ID 对应的字符串。
代码结构:
tree
.
├── bin
│ └── httpbin
├── go.mod
├── go.sum
├── httpbin
│ ├── api.go
│ ├── core.go
│ └── db.go
├── main.go
└── README.md
2 directories, 8 files
模块相关
go mod init httpbin
如果有新的依赖引入,需要执行 go mod tidy
命令来更新 go.mod 和 go.sum 文件。
PS: 编译:go build -o bin/
HTTP 相关
- 创建 HTTP 服务器
http.Server
- 定义处理请求
func Handle(w http.ResponseWriter, r *http.Request)
- 路由
http.HandleFunc
- 启动服务
http.ListenAndServe
http.Request
r.Method string
r.URL.Path string
r.Header map[string][]string
r.Body io.ReadCloser
r.Form url.Values
r.Body.Read()
r.Body = http.MaxBytesReader(w, r.Body, 1024)
content, err := ioutil.ReadAll(r.Body)
r.FormValue()
r.Form["key"]
http.ResponseWriter
http.Error(w, "Not found", http.StatusNotFound)
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
w.Write([]byte(content))
数据库 (MySQL) 相关
需要导入 database/sql
包和 github.com/go-sql-driver/mysql
包:
import (
"database/sql"
_ "github.com/go-sql-driver/mysql"
)
数据库操作:
db, err := sql.Open("mysql", "root:123456@tcp(localhost:3306)/httpbin?charset=utf8")
db.Ping()
// func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
// return db.QueryContext(context.Background(), query, args...)
// }
// func (db *DB) Exec(query string, args ...interface{}) (Result, error) {
// return db.ExecContext(context.Background(), query, args...)
// }
stmt := "insert into httpbin (req_id, content) values (?, ?);"
result, err := db.Exec(stmt, id, content)
if err != nil {
panic(err)
}
stmt := "select content from httpbin where req_id = ?;"
rows, err := db.Query(stmt, id)
if err != nil {
panic(err)
}
defer rows.Close()
content := ""
if !rows.Next() {
// 没有数据
} else {
err := rows.Scan(&content)
if err != nil {
panic(err)
}
}
日志操作
log.Printf("[WARN] GET /%s 400 Not found", id)
其他
- 时间
time
- 随机字符串
crypto/rand
- Base64
encoding/base64
- 类型转换
[]byte
和string
int64
和[]byte