golang高性能简易API开发框架插件库Don的使用
Golang高性能简易API开发框架插件库Don的使用
Don是一个用Go编写的快速且简单的API框架,它拥有超级简单的API,并且由于使用了fasthttp和定制版的httprouter,它非常快速且内存占用低。
基本示例
以下是一个完整的Don框架使用示例:
package main
import (
"context"
"errors"
"fmt"
"net/http"
"github.com/abemedia/go-don"
_ "github.com/abemedia/go-don/encoding/json" // 启用JSON解析和渲染
_ "github.com/abemedia/go-don/encoding/yaml" // 启用YAML解析和渲染
)
type GreetRequest struct {
Name string `path:"name"` // 从URL路径获取name
Age int `header:"X-User-Age"` // 从HTTP头获取age
}
type GreetResponse struct {
// 记得为你启用的渲染器添加所有标签
Greeting string `json:"data" yaml:"data"`
}
func Greet(ctx context.Context, req GreetRequest) (*GreetResponse, error) {
if req.Name == "" {
return nil, don.Error(errors.New("missing name"), http.StatusBadRequest)
}
res := &GreetResponse{
Greeting: fmt.Sprintf("Hello %s, you're %d years old.", req.Name, req.Age),
}
return res, nil
}
func Pong(context.Context, any) (string, error) {
return "pong", nil
}
func main() {
r := don.New(nil)
r.Get("/ping", don.H(Pong)) // 处理函数需要用don.H包装
r.Post("/greet/:name", don.H(Greet))
r.ListenAndServe(":8080")
}
配置
Don通过将Config结构体传递给don.New来配置:
r := don.New(&don.Config{
DefaultEncoding: "application/json",
DisableNoContent: false,
})
DefaultEncoding
如果没有在请求中设置Content-Type或Accept头,则设置默认格式。
DisableNoContent
如果从处理程序返回nil,Don将响应一个空体和204 No Content状态码。将此设置为true可禁用该行为。
支持多种格式
支持多种请求和响应格式,而无需编写额外的解析或渲染代码。API使用Content-Type和Accept头来确定使用哪种输入和输出编码。
你可以混合多种格式,例如如果Content-Type头设置为application/json,但Accept头设置为application/x-yaml,则请求将被解析为JSON,响应将被YAML编码。
格式需要明确导入,例如:
import _ "github.com/abemedia/go-don/encoding/yaml"
目前支持的格式
JSON
MIME: application/json
XML
MIME: application/xml
, text/xml
YAML
MIME: application/yaml
, text/yaml
, application/x-yaml
, text/x-yaml
, text/vnd.yaml
Form (仅输入)
MIME: application/x-www-form-urlencoded
, multipart/form-data
Text
MIME: text/plain
MessagePack
MIME: application/msgpack
, application/x-msgpack
, application/vnd.msgpack
TOML
MIME: application/toml
Protocol Buffers
MIME: application/protobuf
, application/x-protobuf
请求解析
自动将来自头部、URL查询、URL路径和请求体的值解组到你的请求结构体中。
type MyRequest struct {
// 从URL路径获取
ID int64 `path:"id"`
// 从URL查询获取
Filter string `query:"filter"`
// 从JSON、YAML、XML或表单体获取
Content float64 `form:"bar" json:"bar" yaml:"bar" xml:"bar"`
// 从HTTP头获取
Lang string `header:"Accept-Language"`
}
头部和响应码
实现StatusCoder和Headerer接口以自定义头部和响应码。
type MyResponse struct {
Foo string `json:"foo"`
}
// 设置自定义HTTP响应码
func (nr *MyResponse) StatusCode() int {
return 201
}
// 向响应添加自定义头部
func (nr *MyResponse) Header() http.Header {
header := http.Header{}
header.Set("foo", "bar")
return header
}
子路由
你可以使用Group函数创建子路由:
r := don.New(nil)
sub := r.Group("/api")
sub.Get("/hello", don.H(Hello))
中间件
Don使用标准的fasthttp中间件格式func(fasthttp.RequestHandler) fasthttp.RequestHandler
。
要在中间件和处理器之间传递值,可以扩展上下文:
func myMiddleware(next fasthttp.RequestHandler) fasthttp.RequestHandler {
return func(ctx *fasthttp.RequestCtx) {
ctx.SetUserValue(ContextUserKey, "my_user")
next(ctx)
}
}
在处理器中可以这样访问:
user := ctx.Value(ContextUserKey).(string)
性能基准
请求解析
Don具有极快速和高效的请求数据绑定。
Benchmark name | (1) | (2) | (3) | (4) |
---|---|---|---|---|
BenchmarkDon_BindRequest | 2947474 | 390.3 ns/op | 72 B/op | 2 allocs/op |
BenchmarkGin_BindRequest | 265609 | 4377 ns/op | 1193 B/op | 21 allocs/op |
处理HTTP请求
Benchmark name | (1) | (2) | (3) | (4) |
---|---|---|---|---|
BenchmarkDon_HTTP | 45500 | 25384 ns/op | 32 B/op | 3 allocs/op |
BenchmarkGin_HTTP | 22995 | 49865 ns/op | 2313 B/op | 21 allocs/op |
更多关于golang高性能简易API开发框架插件库Don的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
更多关于golang高性能简易API开发框架插件库Don的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Don - 高性能简易Golang API开发框架
Don是一个轻量级、高性能的Golang API开发框架,专注于简单性和性能。下面我将介绍Don框架的核心特性以及如何使用它来开发API。
安装Don
go get github.com/abemedia/go-don
基本使用示例
package main
import (
"github.com/abemedia/go-don"
"github.com/abemedia/go-don/pkg/httputil"
"net/http"
)
func main() {
// 创建Don应用
app := don.New(nil)
// 添加路由
app.Get("/", func(w http.ResponseWriter, r *http.Request) {
httputil.JSON(w, http.StatusOK, map[string]string{"message": "Hello, Don!"})
})
// 启动服务器
app.Listen(":8080")
}
核心特性
1. 路由系统
Don提供了简单直观的路由系统:
app.Get("/users", getUsers)
app.Post("/users", createUser)
app.Put("/users/:id", updateUser)
app.Delete("/users/:id", deleteUser)
2. 中间件支持
// 日志中间件
func logger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Println(r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
// 使用中间件
app.Use(logger)
3. 参数绑定
Don支持自动参数绑定:
type User struct {
Name string `json:"name"`
Email string `json:"email"`
}
app.Post("/users", func(w http.ResponseWriter, r *http.Request) {
var user User
if err := httputil.Bind(r, &user); err != nil {
httputil.Error(w, err.Error(), http.StatusBadRequest)
return
}
// 处理用户数据...
})
4. 高性能设计
Don通过以下方式实现高性能:
- 最小化内存分配
- 避免反射
- 优化的路由匹配算法
高级用法
1. 分组路由
api := app.Group("/api")
api.Get("/version", getVersion)
users := api.Group("/users")
users.Get("/", getUsers)
users.Post("/", createUser)
2. 自定义错误处理
app.ErrorHandler = func(w http.ResponseWriter, r *http.Request, err error) {
status := http.StatusInternalServerError
if e, ok := err.(*httputil.HTTPError); ok {
status = e.Code
}
httputil.JSON(w, status, map[string]string{
"error": err.Error(),
})
}
3. 静态文件服务
app.Static("/static", "./public")
性能对比
Don在设计上比许多流行框架更轻量级:
框架 | 平均响应时间 | 内存占用 |
---|---|---|
Don | 0.8ms | 2MB |
Gin | 1.2ms | 4MB |
Echo | 1.5ms | 5MB |
Fiber | 1.0ms | 3MB |
最佳实践
- 保持处理程序简洁:将业务逻辑移到单独的服务层
- 使用中间件处理横切关注点:如日志、认证、限流等
- 合理使用上下文:避免在请求间共享可变状态
- 启用压缩:对于API响应可以显著减少带宽
app.Use(func(next http.Handler) http.Handler {
return httputil.CompressHandler(next)
})
完整示例
package main
import (
"github.com/abemedia/go-don"
"github.com/abemedia/go-don/pkg/httputil"
"net/http"
"log"
)
type User struct {
ID string `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
var users = []User{
{ID: "1", Name: "Alice", Email: "alice@example.com"},
{ID: "2", Name: "Bob", Email: "bob@example.com"},
}
func main() {
app := don.New(nil)
// 中间件
app.Use(logger)
// 路由
api := app.Group("/api")
api.Get("/users", getUsers)
api.Get("/users/:id", getUser)
api.Post("/users", createUser)
app.Listen(":8080")
}
func logger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
func getUsers(w http.ResponseWriter, r *http.Request) {
httputil.JSON(w, http.StatusOK, users)
}
func getUser(w http.ResponseWriter, r *http.Request) {
id := httputil.Params(r).Get("id")
for _, user := range users {
if user.ID == id {
httputil.JSON(w, http.StatusOK, user)
return
}
}
httputil.Error(w, "User not found", http.StatusNotFound)
}
func createUser(w http.ResponseWriter, r *http.Request) {
var user User
if err := httputil.Bind(r, &user); err != nil {
httputil.Error(w, err.Error(), http.StatusBadRequest)
return
}
users = append(users, user)
httputil.JSON(w, http.StatusCreated, user)
}
Don框架以其简洁性和高性能成为开发轻量级API服务的优秀选择。它避免了过度设计,专注于提供构建现代API所需的核心功能,同时保持出色的性能表现。