在上一节,我们演示了怎么使用jwt鉴权,相信你已经掌握了对jwt的基本使用,本节我们来看一下api服务中间件怎么使用。
中间件分类
在go-zero中,中间件可以分为路由中间件和全局中间件,路由中间件是指某一些特定路由需要实现中间件逻辑,其和jwt类似,没有放在jwt:xxx下的路由不会使用中间件功能, 而全局中间件的服务范围则是整个服务。
中间件使用
这里以search服务为例来演示中间件的使用
路由中间件
重新编写search.api文件,添加middleware声明
$ cd service/search/cmd/api$ vim search.api
@server(jwt: Authmiddleware: Example // 路由中间件声明)service search-api {@handler searchget /search/do (SearchReq) returns (SearchReply)}
重新生成api代码
$ goctl api go -api search.api -dir .
etc/search-api.yaml exists, ignored generationinternal/config/config.go exists, ignored generationsearch.go exists, ignored generationinternal/svc/servicecontext.go exists, ignored generationinternal/handler/searchhandler.go exists, ignored generationinternal/handler/pinghandler.go exists, ignored generationinternal/logic/searchlogic.go exists, ignored generationinternal/logic/pinglogic.go exists, ignored generationDone.
生成完后会在internal目录下多一个middleware的目录,这里即中间件文件,后续中间件的实现逻辑也在这里编写。
完善资源依赖ServiceContext
$ vim service/search/cmd/api/internal/svc/servicecontext.go
type ServiceContext struct {Config config.ConfigExample rest.Middleware}func NewServiceContext(c config.Config) *ServiceContext {return &ServiceContext{Config: c,Example: middleware.NewExampleMiddleware().Handle,}}
编写中间件逻辑 这里仅添加一行日志,内容example middle,如果服务运行输出example middle则代表中间件使用起来了。
$ vim service/search/cmd/api/internal/middleware/examplemiddleware.go
func (m *ExampleMiddleware) Handle(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {logx.Info("example middle")next(w, r)}}
启动服务验证 ```json {“@timestamp”:”2021-02-09T11:32:57.931+08”,”level”:”info”,”content”:”example middle”}
<a name="cu3AU"></a>### 全局中间件通过**rest.Server**提供的**Use**方法即可```gofunc main() {flag.Parse()var c config.Configconf.MustLoad(*configFile, &c)ctx := svc.NewServiceContext(c)server := rest.MustNewServer(c.RestConf)defer server.Stop()// 全局中间件server.Use(func(next http.HandlerFunc) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {logx.Info("global middleware")next(w, r)}})handler.RegisterHandlers(server, ctx)fmt.Printf("Starting server at %s:%d...\n", c.Host, c.Port)server.Start()}
{"@timestamp":"2021-02-09T11:50:15.388+08","level":"info","content":"global middleware"}
