go #源码分析 #v1.0.0 #学习

概述

这里我从 internal/apiserver/server.go 文件中的 initRouter(s.genericAPIServer.Engine) 代码进行路由的注册分析, 主要学习目标如何利用接口将 api 与 api server 进行分离.

apiserver.initRouter

internal/apiserver/router.go

这个函数只是一个引子函数, 用于调用 Middleware 和 api 初始化. 这里可以看出项目使用的内部路由框架由 gin 提供.

  1. func initRouter(g *gin.Engine) {
  2. installMiddleware(g)
  3. installAPI(g)
  4. }

installMiddleware 函数是一个空函数, 我们不做分析. 下面进入 installAPI 分析其实现方式.

apiserver.installAPI

internal/apiserver/router.go

installAPI 是 API 处理函数与路由绑定注册的位置值. 下面对每组 API 的大致内容进行分析

  1. func installAPI(g *gin.Engine) *gin.Engine {
  2. // Middlewares.
  3. jwtStrategy, _ := newJWTAuth().(auth.JWTStrategy)
  4. g.POST("/login", jwtStrategy.LoginHandler)
  5. g.POST("/logout", jwtStrategy.LogoutHandler)
  6. // Refresh time can be longer than token timeout
  7. g.POST("/refresh", jwtStrategy.RefreshHandler)
  8. auto := newAutoAuth()
  9. g.NoRoute(auto.AuthFunc(), func(c *gin.Context) {
  10. core.WriteResponse(c, errors.WithCode(code.ErrPageNotFound, "Page not found."), nil)
  11. })
  12. // v1 handlers, requiring authentication
  13. storeIns, _ := mysql.GetMySQLFactoryOr(nil)
  14. v1 := g.Group("/v1")
  15. {
  16. // user RESTful resource
  17. userv1 := v1.Group("/users")
  18. {
  19. userHandler := user.NewUserHandler(storeIns)
  20. userv1.POST("", userHandler.Create)
  21. userv1.Use(auto.AuthFunc(), middleware.Validation())
  22. // v1.PUT("/find_password", userHandler.FindPassword)
  23. userv1.DELETE("", userHandler.DeleteCollection) // admin api
  24. userv1.DELETE(":name", userHandler.Delete) // admin api
  25. userv1.PUT(":name/change-password", userHandler.ChangePassword)
  26. userv1.PUT(":name", userHandler.Update)
  27. userv1.GET("", userHandler.List)
  28. userv1.GET(":name", userHandler.Get) // admin api
  29. }
  30. v1.Use(auto.AuthFunc())
  31. // policy RESTful resource
  32. policyv1 := v1.Group("/policies", middleware.Publish())
  33. {
  34. policyHandler := policy.NewPolicyHandler(storeIns)
  35. policyv1.POST("", policyHandler.Create)
  36. policyv1.DELETE("", policyHandler.DeleteCollection)
  37. policyv1.DELETE(":name", policyHandler.Delete)
  38. policyv1.PUT(":name", policyHandler.Update)
  39. policyv1.GET("", policyHandler.List)
  40. policyv1.GET(":name", policyHandler.Get)
  41. }
  42. // secret RESTful resource
  43. secretv1 := v1.Group("/secrets", middleware.Publish())
  44. {
  45. secretHandler := secret.NewSecretHandler(storeIns)
  46. secretv1.POST("", secretHandler.Create)
  47. secretv1.DELETE(":name", secretHandler.Delete)
  48. secretv1.PUT(":name", secretHandler.Update)
  49. secretv1.GET("", secretHandler.List)
  50. secretv1.GET(":name", secretHandler.Get)
  51. }
  52. }
  53. return g
  54. }
  • 第 3 - 7 行 jwt 中间件的 登陆, 登出, 刷新token API 的注册.
  • 第 9 - 12 行 目前未知.
  • 第 16 - 60 行 v1 版本的 api 注册.
  • 第 19 - 32 行 用户api 注册.
  • 第 37 - 47 行 策略api 注册.
  • 第 50 -59 行 secret api 注册.

其中配置中间件和路由注册内容都是全部手动实现, 没有什么分析的必要, 下面对每个 Hnadler 进行学习。

Handler 学习

这里分析发现 handler 的结构设计比较巧妙这里, 先对其结构进行分析说明.

UserHandler

UserHandler 由 Service 和 Factory 两个接口组成. 这里的关键使用到了接口, Service 的实现和 Store 的实现可以随时替换!

  1. type UserHandler struct {
  2. srv srvv1.Service
  3. store store.Factory
  4. }
  5. func NewUserHandler(store store.Factory) *UserHandler {
  6. return &UserHandler{
  7. srv: srvv1.NewService(store),
  8. store: store,
  9. }
  10. }

Service 接口

  1. type Service interface {
  2. Users() UserSrv
  3. Secrets() SecretSrv
  4. Policies() PolicySrv
  5. }
  1. type UserSrv interface {
  2. Create(ctx context.Context, user *v1.User, opts metav1.CreateOptions) error
  3. Update(ctx context.Context, user *v1.User, opts metav1.UpdateOptions) error
  4. Delete(ctx context.Context, username string, opts metav1.DeleteOptions) error
  5. DeleteCollection(ctx context.Context, usernames []string, opts metav1.DeleteOptions) error
  6. Get(ctx context.Context, username string, opts metav1.GetOptions) (*v1.User, error)
  7. List(ctx context.Context, opts metav1.ListOptions) (*v1.UserList, error)
  8. ListWithBadPerformance(ctx context.Context, opts metav1.ListOptions) (*v1.UserList, error)
  9. ChangePassword(ctx context.Context, user *v1.User) error
  10. }

Factory 接口

  1. type Factory interface {
  2. Users() UserStore
  3. Secrets() SecretStore
  4. Policies() PolicyStore
  5. Close() error
  6. }
  1. type UserStore interface {
  2. Create(ctx context.Context, user *v1.User, opts metav1.CreateOptions) error
  3. Update(ctx context.Context, user *v1.User, opts metav1.UpdateOptions) error
  4. Delete(ctx context.Context, username string, opts metav1.DeleteOptions) error
  5. DeleteCollection(ctx context.Context, usernames []string, opts metav1.DeleteOptions) error
  6. Get(ctx context.Context, username string, opts metav1.GetOptions) (*v1.User, error)
  7. List(ctx context.Context, opts metav1.ListOptions) (*v1.UserList, error)
  8. }