go - 将文件系统添加到现有 http api Web 服务器的最佳方法
问题描述
我已经有一个 Web 服务器并且它工作正常,现在我想将 fileSystem 模块添加到它。
项目概览如下。
// Custom router
type Handler func(ctx context.Context, w http.ResponseWriter, r *http.Request) error
type Middleware func(Handler) Handler
type App struct {
mux *chi.Mux
och *ochttp.Handler
mw []Middleware
}
func NewApp(mw ...Middleware) *App {
app := App{
mux: chi.NewRouter(),
mw: mw,
}
app.och = &ochttp.Handler{
Handler: app.mux,
Propagation: &tracecontext.HTTPFormat{},
}
return &app
}
func (a *App) Handle(verb, path string, handler Handler, mw ...Middleware) {
handler = wrapMiddleware(a.mw, handler)
h := func(w http.ResponseWriter, r *http.Request) {
...
}
a.mux.MethodFunc(verb, path, h)
}
func (a *App) ServeHTTP(w http.ResponseWriter, r *http.Request) {
a.och.ServeHTTP(w, r)
}
// route
func API(...) http.Handler {
app := web.NewApp(mid.Logger(log)...)
s := Something{
...
}
app.Handle("GET", "/v1/somthing", s.DoSomething)
return app
}
// Handler
type Something struct {
...
}
func (s *Something) DoSomething(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
...
}
// main
api := http.Server{
...
Handler: API(...),
}
go func() {
api.ListenAndServe()
}()
app 结构是一个自定义路由器,它包含第三个路由器、跟踪库和一些中间件。Handler 类型是用于中间件和任何 api 处理程序注册到此路由器的特定 Handler 格式。因为这个项目硬编码只有一个Handler,那么添加另一个像fileSystem这样的Handler最好呢?
解决方案
http.Handler 和 Handler 通过闭包进行转换。
// http.Handler to Handler
func NewHandler(h http.Handler) Handler {
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
h.ServeHTTP(w, r)
}
}
// Handler to http.Handler
func NewHTTPHandler(h Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
h(context.Background(), w, r)
})
}
// or Handler implement http.Handler
func (fn Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
fn(context.Background(), w, r)
}
app.Handle("ANY","/fs/*", NewHandler(http.FileServer(http.Dir("public"))))
type Handler func (Context)
是最好的 Handler 定义。通过请求context.Context对象或者通过属性http.Request.Context()
获取顶层context.Context 。http.Server.BaseContext
中间件最好的实现思路有echo或者gin框架使用的两种方法,但是echo方法不应该复制内存分配浪费。
建议自己实现路由器。在主流框架和路由存货中,没有路由优先级,比如echo gin httprouter gorilla/mux等大量库。
以下是我设计了 22 个月的框架和最简单的实现。
我的网络框架:https ://github.com/eudore/eudore
简单的框架:https ://github.com/eudore/eudore/wiki/3.2-frame-mirco-web
推荐阅读
- qt - 如何使 QtChart 不在某些范围内绘制折线图?
- .htaccess - 使用 htaccess 屏蔽子域
- javascript - Firestore 查询未使用 startAfter 运行
- python - 如何使提交框与 sql/sqlite 和烧瓶、python 一起使用?
- powerbi - 如何在dax中获得总计的最大值
- python - 为什么这个八边形不适合窗户?
- python - 无法访问其中包含列表的嵌套 Python 字典
- c++ - 为什么 atomic_is_lock_free 在 mac 上不能正确链接?
- tensorflow - Tensorflow Federated TFF 仍然是一个模拟环境?
- angular - Angular - 如何正确实现加载拦截器