一、实现未注册路由
小伙伴们都知道,kratos框架使用的是proto定义路由,应该用什么办法去统一处理未注册路由呢?
这里提供一种思路:
1、kratos并不提供NotFound方法注册,也就是没办法直接实现未注册路由的统一处理
2、引入mux库,因为它提供了NotFound的方法注册,可以统一处理未注册的路由
3、kratos注册的路由统一规范的前缀,例如api/v1,api/v2
4、通过统一路由前缀把kratos注册到mux里,这样非kratos路由就可以认为是未定义的路由了
5、注册mux的NotFound方法即可实现未注册路由统一处理
下面我们来看看代码示例:
golang
func NewHTTPServer(c *conf.Server,
webhookServicev1 *service.WebhookServiceV1,
) *transhttp.Server {
var opts []transhttp.ServerOption
opts = []transhttp.ServerOption{
transhttp.Middleware(
recovery.Recovery(),
),
}
srv := transhttp.NewServer(opts...)
// 用mux处理未定义路由统一处理
m := http.NewServeMux()
router := mux.NewRouter()
router.NotFoundHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
err := webhookServicev1.ThirdGameReport(w, r)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(err.Error()))
}
})
m.Handle("/", router)
// 匹配kratos路由,前缀/api/v1走kratos
v1.RegisterWebhookV1HTTPServer(srv, webhookServicev1)
m.Handle("/api/v1/", http.StripPrefix("/api/v1", srv))
// 匹配kratos路由,前缀/api/v2走kratos
m.Handle("/api/v2/", http.StripPrefix("/api/v2", srv))
http.ListenAndServe(c.Http.Addr, m)
return srv
}
二、引入其他标准http服务
asynqmon是一个任务系统的后台管理服务,他是一个标准的http服务,可以让我们能够接入到我们的服务里面去。
例如我要把路由前缀为/asynqmon的都指向到第三方标准http服务asynqmon里,因为asynqmon服务下也会有很多的路由,我们只要用kratos的HandlePrefix路由前缀方法注册整个前缀的路由即可,这样不管是/asynqmon/a还是/asynqmon/b都会指向asynqmon服务,看代码示例:
golang
func NewHTTPServer(c *conf.Server, auth *conf.Auth,
gameServicev1 *service.GameServiceV1,
) *http.Server {
var opts []http.ServerOption
opts = []http.ServerOption{
http.Middleware(
recovery.Recovery(),
),
}
opts = append(opts, http.RequestDecoder(DefaultRequestDecoder))
srv := http.NewServer(opts...)
// asynq后台服务,这是第三方库提供的标准http服务
mon := asynqmon.New(asynqmon.Options{
RootPath: "/asynqmon", // RootPath is the root URL path where asynqmon will be hosted.
RedisConnOpt: asynq.RedisClientOpt{},
})
handler := &Handler{}
// 路由前缀为/asynqmon的都走到handler,也就是第三方的标准http服务
srv.HandlePrefix("/asynqmon", handler)
v1.RegisterGameV1HTTPServer(srv, gameServicev1)
return srv
}
type Handler struct {
}
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.Mon.ServeHTTP(w, r)
}