首页 > 解决方案 > 将文件系统添加到现有 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最好呢?

标签: go

解决方案


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


推荐阅读