definition 包

definition 包包含了 Nirvana 的 API 定义,用于描述 API 的参数与返回值。

  1. // Chain contains all subsequent actions.
  2. type Chain interface {
  3. // Continue continues to execute the next subsequent actions.
  4. Continue(context.Context) error
  5. }
  6. // Middleware describes the form of middlewares. If you want to
  7. // carry on, call Chain.Continue() and pass the context.
  8. type Middleware func(context.Context, Chain) error
  9. // Operator is used to operate an object and return an replacement object.
  10. //
  11. // For example:
  12. // A converter:
  13. // type ConverterForAnObject struct{}
  14. // func (c *ConverterForAnObject) Kind() {return "converter"}
  15. // func (c *ConverterForAnObject) In() reflect.Type {return definition.TypeOf(&ObjectV1{})}
  16. // func (c *ConverterForAnObject) Out() reflect.Type {return definition.TypeOf(&ObjectV2{})}
  17. // func (c *ConverterForAnObject) Operate(ctx context.Context, object interface{}) (interface{}, error) {
  18. // objV2, err := convertObjectV1ToObjectV2(object.(*ObjectV1))
  19. // return objV2, err
  20. // }
  21. //
  22. // A validator:
  23. // type ValidatorForAnObject struct{}
  24. // func (c *ValidatorForAnObject) Kind() {return "validator"}
  25. // func (c *ValidatorForAnObject) In() reflect.Type {return definition.TypeOf(&Object{})}
  26. // func (c *ValidatorForAnObject) Out() reflect.Type {return definition.TypeOf(&Object{})}
  27. // func (c *ValidatorForAnObject) Operate(ctx context.Context, object interface{}) (interface{}, error) {
  28. // if err := validate(object.(*Object)); err != nil {
  29. // return nil, err
  30. // }
  31. // return object, nil
  32. // }
  33. type Operator interface {
  34. // Kind indicates operator type.
  35. Kind() string
  36. // In returns the type of the only object parameter of operator.
  37. // The type must be a concrete struct or built-in type. It should
  38. // not be interface unless it's a file or stream reader.
  39. In() reflect.Type
  40. // Out returns the type of the only object result of operator.
  41. // The type must be a concrete struct or built-in type. It should
  42. // not be interface unless it's a file or stream reader.
  43. Out() reflect.Type
  44. // Operate operates an object and return one.
  45. Operate(ctx context.Context, field string, object interface{}) (interface{}, error)
  46. }
  47. // Method is an alternative of HTTP method. It's more clearer than HTTP method.
  48. // A definition method binds a certain HTTP method and a success status code.
  49. type Method string
  50. const (
  51. // List binds to http.MethodGet and code http.StatusOK(200).
  52. List Method = "List"
  53. // Get binds to http.MethodGet and code http.StatusOK(200).
  54. Get Method = "Get"
  55. // Create binds to http.MethodPost and code http.StatusCreated(201).
  56. Create Method = "Create"
  57. // Update binds to http.MethodPut and code http.StatusOK(200).
  58. Update Method = "Update"
  59. // Patch binds to http.MethodPatch and code http.StatusOK(200).
  60. Patch Method = "Patch"
  61. // Delete binds to http.MethodDelete and code http.StatusNoContent(204).
  62. Delete Method = "Delete"
  63. // AsyncCreate binds to http.MethodPost and code http.StatusAccepted(202).
  64. AsyncCreate Method = "AsyncCreate"
  65. // AsyncUpdate binds to http.MethodPut and code http.StatusAccepted(202).
  66. AsyncUpdate Method = "AsyncUpdate"
  67. // AsyncPatch binds to http.MethodPatch and code http.StatusAccepted(202).
  68. AsyncPatch Method = "AsyncPatch"
  69. // AsyncDelete binds to http.MethodDelete and code http.StatusAccepted(202).
  70. AsyncDelete Method = "AsyncDelete"
  71. )
  72. // Source indicates which place a value is from.
  73. type Source string
  74. const (
  75. // Path means value is from URL path.
  76. Path Source = "Path"
  77. // Query means value is from URL query string.
  78. Query Source = "Query"
  79. // Header means value is from request header.
  80. Header Source = "Header"
  81. // Form means value is from request body and content type must be
  82. // "application/x-www-form-urlencoded" and "multipart/form-data".
  83. Form Source = "Form"
  84. // File means value is from request body and content type must be
  85. // "multipart/form-data".
  86. File Source = "File"
  87. // Body means value is from request body.
  88. Body Source = "Body"
  89. // Auto identifies a struct and generate field values by field tag.
  90. //
  91. // Tag name is "source". Its value format is "Source,Name".
  92. //
  93. // ex.
  94. // type Example struct {
  95. // Start int `source:"Query,start"`
  96. // ContentType string `source:"Header,Content-Type"`
  97. // }
  98. Auto Source = "Auto"
  99. // Prefab means value is from a prefab generator.
  100. // A prefab combines data to generate value.
  101. Prefab Source = "Prefab"
  102. )
  103. // Destination indicates the target type to place function results.
  104. type Destination string
  105. const (
  106. // Meta means result will be set into the header of response.
  107. Meta Destination = "Meta"
  108. // Data means result will be set into the body of response.
  109. Data Destination = "Data"
  110. // Error means the result is an error and should be treated specially.
  111. // An error occurs indicates that there is no data to return. So the
  112. // error should be treated as data and be writed back to client.
  113. Error Destination = "Error"
  114. )
  115. // Example is just an example.
  116. type Example struct {
  117. // Description describes the example.
  118. Description string
  119. // Instance is a custom data.
  120. Instance interface{}
  121. }
  122. // Parameter describes a function parameter.
  123. type Parameter struct {
  124. // Source is the parameter value generated from.
  125. Source Source
  126. // Name is the name to get value from a request.
  127. // ex. a query name, a header key, etc.
  128. Name string
  129. // Default value is used when a request does not provide a value
  130. // for the parameter.
  131. Default interface{}
  132. // Operators can modify and validate the target value.
  133. // Parameter value is passed to the first operator, then
  134. // previous operator's result is as next operator's parameter.
  135. // The result of last operator will be passed to target function.
  136. Operators []Operator
  137. // Description describes the parameter.
  138. Description string
  139. }
  140. // Result describes how to handle a result from function results.
  141. type Result struct {
  142. // Destination is the target for the result. Different types make different behavior.
  143. Destination Destination
  144. // Operators can modify the result value.
  145. // Result value is passed to the first operator, then
  146. // previous operator's result is as next operator's parameter.
  147. // The result of last operator will be passed to destination handler.
  148. Operators []Operator
  149. // Description describes the result.
  150. Description string
  151. }
  152. // Definition defines an API handler.
  153. type Definition struct {
  154. // Method is definition method.
  155. Method Method
  156. // Consumes indicates how many content types the handler can consume.
  157. // It will override parent descriptor's consumes.
  158. Consumes []string
  159. // Produces indicates how many content types the handler can produce.
  160. // It will override parent descriptor's produces.
  161. Produces []string
  162. // ErrorProduces is used to generate data for error. If this field is empty,
  163. // it means that this field equals to Produces.
  164. // In some cases, succeessful data and error data should be generated in
  165. // different ways.
  166. ErrorProduces []string
  167. // Function is a function handler. It must be func type.
  168. Function interface{}
  169. // Parameters describes function parameters.
  170. Parameters []Parameter
  171. // Results describes function retrun values.
  172. Results []Result
  173. // Summary is a one-line brief description of this definition.
  174. Summary string
  175. // Description describes the API handler.
  176. Description string
  177. // Examples contains many examples for the API handler.
  178. Examples []Example
  179. }
  180. // Descriptor describes a descriptor for API definitions.
  181. type Descriptor struct {
  182. // Path is the url path. It will inherit parent's path.
  183. //
  184. // If parent path is "/api/v1", current is "/some",
  185. // It means current definitions handles "/api/v1/some".
  186. Path string
  187. // Consumes indicates content types that current definitions
  188. // and child definitions can consume.
  189. // It will override parent descriptor's consumes.
  190. Consumes []string
  191. // Produces indicates content types that current definitions
  192. // and child definitions can produce.
  193. // It will override parent descriptor's produces.
  194. Produces []string
  195. // Middlewares contains path middlewares.
  196. Middlewares []Middleware
  197. // Definitions contains definitions for current path.
  198. Definitions []Definition
  199. // Children is used to place sub-descriptors.
  200. Children []Descriptor
  201. // Description describes the usage of the path.
  202. Description string
  203. }

Descriptor 结构体包含具有如下含义的字段:

  1. API 路径
  2. 可被 Middlewares,Definitions,Children 继承的字段
  3. 其他与 API 路径同等级别的字段

如果希望对 Descriptor 进行扩展,需要遵守上面这些规则。

Definition 结构体包含了一个具体的 API 定义:

  1. API 方法,这个方法是一个抽象方法,用于描述一种行为(比如 Create)。
  2. API 参数和返回值定义
  3. 其他与具体 API 同等级别的字段

如果希望对 Definition 进行扩展,需要遵守上面这些规则。

Parameter 和 Result 分别对应 API 的参数和返回值,与业务函数的参数与返回值一一对应。字段定义与参数和返回值的转换有关。

在上面的定义中,存在两个额外功能:

  1. 在 Descriptor 中提供了 Middleware
  2. 在 Parameter 和 Result 中,提供了 Operator

其中 Middleware 提供了中间件的能力,可以在请求之前让用户对请求进行一些特殊处理。而 Operator 则针对单个的业务参数和返回值,可以对值进行验证和修改。

definition 包除了包含对 API 的定义以外,还提供了一些函数,帮助快速构建 Definitions 和 Operators:

  1. // MIME types
  2. const (
  3. // acceptTypeAll indicates a accept type from http request.
  4. // It means client can receive any content.
  5. // Request content type in header "Content-Type" must not set to "*/*".
  6. // It only can exist in request header "Accept".
  7. // In most time, it locate at the last element of "Accept".
  8. // It's default value if client have not set "Accept" header.
  9. MIMEAll = "*/*"
  10. MIMENone = ""
  11. MIMEText = "text/plain"
  12. MIMEJSON = "application/json"
  13. MIMEXML = "application/xml"
  14. MIMEOctetStream = "application/octet-stream"
  15. MIMEURLEncoded = "application/x-www-form-urlencoded"
  16. MIMEFormData = "multipart/form-data"
  17. )
  18. // OperatorFunc creates operator by function.
  19. // function must has signature:
  20. // func f(context.Context, string, AnyType) (AnyType, error)
  21. // The second parameter is a string that is used to identify field.
  22. // AnyType can be any type in go. But struct type and
  23. // built-in data type is recommended.
  24. func OperatorFunc(kind string, f interface{}) Operator