golang基于httprouter的依赖注入中间件路由插件库nchi的使用
Golang基于httprouter的依赖注入中间件路由插件库nchi的使用
nchi简介
nchi
是一个轻量级、优雅且快速的路由库,用于构建Go HTTP服务。它特别适合编写大型REST API服务,随着项目增长和变化仍能保持可维护性。nchi基于以下两个库构建:
nject
依赖注入框架- 最快的Go http路由器
httprouter
安装
go get github.com/muir/nchi
简单示例
package main
import (
"net/http"
"github.com/muir/nchi"
"github.com/go-chi/chi/v5/middleware"
)
func main() {
r := nchi.NewRouter()
r.Use(middleware.Logger) // 使用日志中间件
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("welcome")) // 根路由处理
})
http.ListenAndServe(":3000", r) // 启动服务器
}
REST API完整示例
package main
import (
//...
"github.com/muir/nchi"
"github.com/muir/nvelope"
"github.com/muir/nject/v2"
"github.com/go-chi/chi/v5/middleware"
)
func main() {
r := nchi.NewRouter()
// 基础中间件栈
r.Use(
middleware.RequestID, // 请求ID
middleware.RealIP, // 真实IP
middleware.Logger, // 日志
nchi.DecodeJSON, // JSON解码
)
// 错误处理中间件
r.Use(func(inner func() error, w http.ResponseWriter) {
err := inner()
if err == nil {
return
}
code := nvelope.GetReturnCode(err)
w.WriteHeader(code)
w.Write([]byte(err.Error()))
})
// 设置请求超时
r.Use(middleware.Timeout(60 * time.Second))
// 简单路由
r.Get("/", func(w http.ResponseWriter) {
w.Write([]byte("hi"))
})
// 文章资源路由
r.Route("/articles", func(r nchi.Router) {
r.With(paginate).Get("/", listArticles) // GET /articles
r.With(paginate).Get("/:month/:day/:year", listArticlesByDate) // GET /articles/01-16-2017
r.Post("/", createArticle) // POST /articles
r.Get("/search", searchArticles) // GET /articles/search
r.Get("/:articleSlug", getArticleBySlug) // GET /articles/home-is-toronto
// 子路由
r.Route("/:articleID", func(r nchi.Router) {
r.Use(LoadArticle) // 加载文章中间件
r.Get("/", getArticle) // GET /articles/123
r.Put("/", updateArticle) // PUT /articles/123
r.Delete("/", deleteArticle) // DELETE /articles/123
})
})
// 挂载管理子路由
r.Mount("/admin", adminRouter())
http.ListenAndServe(":3333", r)
}
// 加载文章依赖注入函数
func LoadArticle(params nchi.Params) (*Article, nject.TerminalError) {
articleID := params.ByName("articleID")
article, err := dbGetArticle(articleID)
if errors.Is(err, sql.NotFound) {
return nil, nvelope.NotFound(err)
}
return article, err
}
// 获取文章处理函数
func getArticle(article *Article, w http.ResponseWriter) {
w.Write([]byte(fmt.Sprintf("title:%s", article.Title)))
}
中间件支持
nchi支持两种形式的中间件:
-
标准中间件:
func(http.HandlerFunc) http.HandlerFunc
func(http.Handler) http.Handler
-
依赖注入中间件
nchi会自动检测标准中间件并将其转换为nject框架可用的形式。
开发状态
nchi目前运行良好,没有太多变化。如果您有任何改进建议,请提交问题。
更多关于golang基于httprouter的依赖注入中间件路由插件库nchi的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang基于httprouter的依赖注入中间件路由插件库nchi的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Golang基于httprouter的依赖注入中间件路由插件库nchi使用指南
nchi是一个基于httprouter构建的轻量级路由库,它提供了依赖注入和中间件支持,非常适合构建RESTful API服务。下面我将详细介绍nchi的使用方法。
安装nchi
go get github.com/muir/nchi
基本使用
package main
import (
"fmt"
"net/http"
"github.com/muir/nchi"
)
func main() {
router := nchi.NewRouter()
router.Get("/", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Hello, World!")
})
http.ListenAndServe(":8080", router)
}
中间件支持
nchi支持中间件链式调用:
func logger(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Printf("Request: %s %s\n", r.Method, r.URL.Path)
next.ServeHTTP(w, r)
})
}
func auth(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token != "secret" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
router := nchi.NewRouter()
// 全局中间件
router.Use(logger)
// 路由组中间件
api := router.Group("/api")
api.Use(auth)
api.Get("/users", func(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "User list")
})
http.ListenAndServe(":8080", router)
}
依赖注入
nchi支持依赖注入,可以将服务注入到处理器中:
type UserService struct {
// 模拟用户服务
}
func (s *UserService) GetUsers() []string {
return []string{"Alice", "Bob", "Charlie"}
}
func main() {
userService := &UserService{}
router := nchi.NewRouter()
// 注入服务到处理器
router.Get("/users", func(w http.ResponseWriter, r *http.Request, s *UserService) {
users := s.GetUsers()
fmt.Fprintf(w, "Users: %v", users)
}).Inject(userService)
http.ListenAndServe(":8080", router)
}
路由参数
nchi继承了httprouter的路由参数特性:
func main() {
router := nchi.NewRouter()
router.Get("/users/:id", func(w http.ResponseWriter, r *http.Request) {
id := nchi.URLParam(r, "id")
fmt.Fprintf(w, "User ID: %s", id)
})
http.ListenAndServe(":8080", router)
}
错误处理
可以自定义错误处理器:
func main() {
router := nchi.NewRouter()
// 自定义404处理器
router.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusNotFound)
fmt.Fprint(w, "Custom 404 page")
})
// 自定义方法不允许处理器
router.MethodNotAllowed = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusMethodNotAllowed)
fmt.Fprint(w, "Method not allowed")
})
http.ListenAndServe(":8080", router)
}
完整示例
package main
import (
"fmt"
"log"
"net/http"
"github.com/muir/nchi"
)
type Database struct {
// 模拟数据库
}
func (db *Database) GetUserName(id string) string {
// 模拟数据库查询
return "User_" + id
}
func authMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Header.Get("X-API-Key") != "secret" {
http.Error(w, "Unauthorized", http.StatusUnauthorized)
return
}
next.ServeHTTP(w, r)
})
}
func main() {
db := &Database{}
router := nchi.NewRouter()
// 全局中间件
router.Use(authMiddleware)
// 用户路由组
userRouter := router.Group("/users")
{
userRouter.Get("/:id", func(w http.ResponseWriter, r *http.Request, db *Database) {
id := nchi.URLParam(r, "id")
name := db.GetUserName(id)
fmt.Fprintf(w, "User: %s", name)
}).Inject(db)
userRouter.Post("/", func(w http.ResponseWriter, r *http.Request) {
// 创建用户逻辑
w.WriteHeader(http.StatusCreated)
fmt.Fprint(w, "User created")
})
}
// 健康检查
router.Get("/health", func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
fmt.Fprint(w, "OK")
})
log.Println("Server started on :8080")
log.Fatal(http.ListenAndServe(":8080", router))
}
总结
nchi结合了httprouter的高性能和依赖注入的便利性,主要特点包括:
- 基于httprouter,性能优异
- 支持中间件链
- 依赖注入支持
- 简洁的API设计
- 支持路由参数和通配符
对于需要构建高性能API且希望简化依赖管理的项目,nchi是一个很好的选择。