Context

以下是 blademaster 中 Context 对象结构体声明的代码片段:

  1. // Context is the most important part. It allows us to pass variables between
  2. // middleware, manage the flow, validate the JSON of a request and render a
  3. // JSON response for example.
  4. type Context struct {
  5. context.Context
  6. Request *http.Request
  7. Writer http.ResponseWriter
  8. // flow control
  9. index int8
  10. handlers []HandlerFunc
  11. // Keys is a key/value pair exclusively for the context of each request.
  12. Keys map[string]interface{}
  13. Error error
  14. method string
  15. engine *Engine
  16. }
  • 首先可以看到 blademaster 的 Context 结构体中会 embed 一个标准库中的 Context 实例,bm 中的 Context 也是直接通过该实例来实现标准库中的 Context 接口。
  • blademaster 会使用配置的 server timeout (默认1s) 作为一次请求整个过程中的超时时间,使用该context调用dao做数据库、缓存操作查询时均会将该超时时间传递下去,一旦抵达deadline,后续相关操作均会返回context deadline exceeded
  • Request 和 Writer 字段用于获取当前请求的与输出响应。
  • index 和 handlers 用于 handler 的流程控制;handlers 中存储了当前请求需要执行的所有 handler,index 用于标记当前正在执行的 handler 的索引位。
  • Keys 用于在 handler 之间传递一些额外的信息。
  • Error 用于存储整个请求处理过程中的错误。
  • method 用于检查当前请求的 Method 是否与预定义的相匹配。
  • engine 字段指向当前 blademaster 的 Engine 实例。

以下为 Context 中所有的公开的方法:

  1. // 用于 Handler 的流程控制
  2. func (c *Context) Abort()
  3. func (c *Context) AbortWithStatus(code int)
  4. func (c *Context) Bytes(code int, contentType string, data ...[]byte)
  5. func (c *Context) IsAborted() bool
  6. func (c *Context) Next()
  7. // 用户获取或者传递请求的额外信息
  8. func (c *Context) RemoteIP() (cip string)
  9. func (c *Context) Set(key string, value interface{})
  10. func (c *Context) Get(key string) (value interface{}, exists bool)
  11. // 用于校验请求的 payload
  12. func (c *Context) Bind(obj interface{}) error
  13. func (c *Context) BindWith(obj interface{}, b binding.Binding) error
  14. // 用于输出响应
  15. func (c *Context) Render(code int, r render.Render)
  16. func (c *Context) Redirect(code int, location string)
  17. func (c *Context) Status(code int)
  18. func (c *Context) String(code int, format string, values ...interface{})
  19. func (c *Context) XML(data interface{}, err error)
  20. func (c *Context) JSON(data interface{}, err error)
  21. func (c *Context) JSONMap(data map[string]interface{}, err error)
  22. func (c *Context) Protobuf(data proto.Message, err error)

所有方法基本上可以分为三类:

  • 流程控制
  • 额外信息传递
  • 请求处理
  • 响应处理

Handler

handler

初次接触blademaster的用户可能会对其Handler的流程处理产生不小的疑惑,实际上bmHandler对处理非常简单:

  • Router模块中预先注册的middleware与其他Handler合并,放入Contexthandlers字段,并将index字段置0
  • 然后通过Next()方法一个个执行下去,部分middleware可能想要在过程中中断整个流程,此时可以使用Abort()方法提前结束处理
  • 有些middleware还想在所有Handler执行完后再执行部分逻辑,此时可以在自身Handler中显式调用Next()方法,并将这些逻辑放在调用了Next()方法之后

扩展阅读

bm快速开始
bm中间件
bm基于pb生成