service 包

service 包实现了 Nirvana 的 API 处理框架:

  1. Service.ServeHTTP()
  2. ----------------------
  3. |-----Filters------|
  4. |---Router Match---|
  5. |-------------Middlewares------------|
  6. |-------------Executor---------------|
  7. |-ParameterGenerators-|-DestinationHandlers-|
  8. |------------User Function-----------|

service 包的入口是 Builder:

  1. // Builder builds service.
  2. type Builder interface {
  3. // Logger returns logger of builder.
  4. Logger() log.Logger
  5. // SetLogger sets logger to server.
  6. SetLogger(logger log.Logger)
  7. // Modifier returns modifier of builder.
  8. Modifier() DefinitionModifier
  9. // SetModifier sets definition modifier.
  10. SetModifier(m DefinitionModifier)
  11. // Filters returns all request filters.
  12. Filters() []Filter
  13. // AddFilters add filters to filter requests.
  14. AddFilter(filters ...Filter)
  15. // AddDescriptors adds descriptors to router.
  16. AddDescriptor(descriptors ...definition.Descriptor) error
  17. // Middlewares returns all router middlewares.
  18. Middlewares() map[string][]definition.Middleware
  19. // Definitions returns all definitions. If a modifier exists, it will be executed.
  20. Definitions() map[string][]definition.Definition
  21. // Build builds a service to handle request.
  22. Build() (Service, error)
  23. }
  24. type Service interface {
  25. http.Handler
  26. }
  27. // DefinitionModifier is used in Server. It's used to modify definition.
  28. // If you want to add some common data into all definitions, you can write
  29. // a customized modifier for it.
  30. type DefinitionModifier func(d *definition.Definition)
  31. // Filter can filter request. It has the highest priority in a request
  32. // lifecycle. It runs before router matching.
  33. // If a filter return false, that means the request should be filtered.
  34. // If a filter want to filter a request, it should handle the request
  35. // by itself.
  36. type Filter func(resp http.ResponseWriter, req *http.Request) bool

Builder 构建 Service 来提供 HTTP 服务。因此 Builder 提供了多个方法用于设置生成服务需要的日志,Definition 修改器,请求过滤器,API 描述符。构建完成的 Service 实际上是一个 http.Handler,用来处理请求。

其中 Definition 修改器用于在生成路由之前修改 API Definition。请求过滤器则是在 Service 执行的时候才会被调用,请求过滤器的优先级高于路由匹配。也就是说,在路由匹配之前,请求就有可能被过滤器直接过滤掉。

Builder 还会将 API Definition 转换为路由需要的数据结构,涉及到以下内容:

  1. 对应 Consumes 和 Produces 的 Consumer 和 Producer
    Consumer 针对请求的 body,将数据转换为业务函数需要的数据类型(通常是结构体)。
    Producer 则是将业务函数的返回值转换并写入到响应的 body 中。

    1. // Consumer handles specifically typed data from a reader and unmarshals it into an object.
    2. type Consumer interface {
    3. // ContentType returns a HTTP MIME type.
    4. ContentType() string
    5. // Consume unmarshals data from r into v.
    6. Consume(r io.Reader, v interface{}) error
    7. }
    8. // Producer marshals an object to specifically typed data and write it into a writer.
    9. type Producer interface {
    10. // ContentType returns a HTTP MIME type.
    11. ContentType() string
    12. // Produce marshals v to data and write to w.
    13. Produce(w io.Writer, v interface{}) error
    14. }
  2. 对应 Prefab 类型的 Prefab 生成器
    这个生成器用于创建业务函数需要的特定实例,一般是服务端实例,即不是从请求里获取的数据而生成的。
    service 包里提供了一个 Context Prefab 生成器,简单的将参数里的 context 返回出去,供业务函数使用。

    1. // Prefab creates instances for internal type. These instances are not
    2. // unmarshaled form http request data.
    3. type Prefab interface {
    4. // Name returns prefab name.
    5. Name() string
    6. // Type is instance type.
    7. Type() reflect.Type
    8. // Make makes an instance.
    9. Make(ctx context.Context) (interface{}, error)
    10. }
  3. 对应 golang 基础类型的转换器
    这些转换器一般是用于将请求里的 query,header 等简单字符串数据转换为 golang 的基础类型,供业务函数使用。

    1. // Converter is used to convert []string to specific type. Data must have one
    2. // element at least or it will panic.
    3. type Converter func(ctx context.Context, data []string) (interface{}, error)
  4. 用于封装请求的 ValueContainer
    这个接口是对 Request 的一次封装,方便获取对应位置的字符串数据。

    1. // ValueContainer contains values from a request.
    2. type ValueContainer interface {
    3. // Path returns path value by key.
    4. Path(key string) (string, bool)
    5. // Query returns value from query string.
    6. Query(key string) ([]string, bool)
    7. // Header returns value by header key.
    8. Header(key string) ([]string, bool)
    9. // Form returns value from request. It is valid when
    10. // http "Content-Type" is "application/x-www-form-urlencoded"
    11. // or "multipart/form-data".
    12. Form(key string) ([]string, bool)
    13. // File returns a file reader when "Content-Type" is "multipart/form-data".
    14. File(key string) (multipart.File, bool)
    15. // Body returns a reader to read data from request body.
    16. // The reader only can read once.
    17. Body() (reader io.ReadCloser, contentType string, ok bool)
    18. }
  5. 用于封装响应的 ResponseWriter
    ResponseWriter 是对 http.ResponseWriter 的一个扩展,提供了一些功能方便中间件使用。

    1. // ResponseWriter extends http.ResponseWriter.
    2. type ResponseWriter interface {
    3. http.ResponseWriter
    4. // HeaderWritable can check whether WriteHeader() has
    5. // been called. If the method returns false, you should
    6. // not recall WriteHeader().
    7. HeaderWritable() bool
    8. // StatusCode returns status code.
    9. StatusCode() int
    10. // ContentLength returns the length of written content.
    11. ContentLength() int
    12. }
  6. 用于合并请求和响应的 Context
    HTTPContext 实现了 Context 接口,包装了请求的信息。作为路由上下文使用。

    1. // HTTPContext describes an http context.
    2. type HTTPContext interface {
    3. Request() *http.Request
    4. ResponseWriter() ResponseWriter
    5. ValueContainer() ValueContainer
    6. RoutePath() string
    7. }
  7. 用于生成业务函数的参数的 ParameterGenerator
    ParameterGenerator 是真正的参数生成器,通过调用 Consumer,Converter,Prefab 等来完成业务函数的参数生成。

    1. // ParameterGenerator is used to generate object for a parameter.
    2. type ParameterGenerator interface {
    3. // Source returns the source generated by current generator.
    4. Source() definition.Source
    5. // Validate validates whether defaultValue and target type is valid.
    6. Validate(name string, defaultValue interface{}, target reflect.Type) error
    7. // Generate generates an object by data from value container.
    8. Generate(ctx context.Context, vc ValueContainer, consumers []Consumer, name string, target reflect.Type) (interface{}, error)
    9. }
  8. 用于将业务函数返回值写入 Response 的 DestinationHandler
    DestinationHandler 是业务函数返回值处理器,通过调用 Producer 将返回值转换为字节写入响应中。
    在 DestinationHandler 中,错误是会进行特殊处理的。如果业务函数返回的错误符合 Error 接口,则会根据这个接口来生成错误码和返回数据结构。

    1. // Error is a common interface for error.
    2. // If an error implements the interface, type handlers can
    3. // use Code() to get a specified HTTP status code.
    4. type Error interface {
    5. // Code is a HTTP status code.
    6. Code() int
    7. // Message is an object which contains information of the error.
    8. Message() interface{}
    9. }
    10. const (
    11. // HighPriority for error type.
    12. // If an error occurs, ignore meta and data.
    13. HighPriority int = 100
    14. // MediumPriority for meta type.
    15. MediumPriority int = 200
    16. // LowPriority for data type.
    17. LowPriority int = 300
    18. )
    19. // DestinationHandler is used to handle the results from API handlers.
    20. type DestinationHandler interface {
    21. // Type returns definition.Type which the type handler can handle.
    22. Destination() definition.Destination
    23. // Priority returns priority of the type handler. Type handler with higher priority will prior execute.
    24. Priority() int
    25. // Validate validates whether the type handler can handle the target type.
    26. Validate(target reflect.Type) error
    27. // Handle handles a value. If the handler has something wrong, it should return an error.
    28. // The handler descides how to deal with value by producers and status code.
    29. // The status code is a success status code. If everything is ok, the handler should use the status code.
    30. //
    31. // There are three cases for return values (goon means go on or continue):
    32. // 1. go on is true, err is nil.
    33. // It means that current type handler did nothing (or looks like did nothing) and next type handler
    34. // should take the context.
    35. // 2. go on is false, err is nil.
    36. // It means that current type handler has finished the context and next type handler should not run.
    37. // 3. err is not nil
    38. // It means that current type handler handled the context but something wrong. All subsequent type
    39. // handlers should not run.
    40. Handle(ctx context.Context, producers []Producer, code int, value interface{}) (goon bool, err error)
    41. }

注:以上每个接口对应的实例都是可以通过相关的函数注册和修改的。