Versions Compared
Key
- This line was added.
- This line was removed.
- Formatting was changed.
路由方法定义
从上面的例子中,我们可以看到,路由方法定义使用固定的格式:
Code Block | ||
---|---|---|
| ||
func Handler(ctx context.Context, req *Request) (res *Response, err error) |
其中输入参数和输出参数都是两个,并且都是必须的一个都不能少。简单介绍下:
参数 | 说明 | 注意事项 |
---|---|---|
ctx context.Context | 上下文 | Server 组件会自动从请求中获取并传递给接口方法 |
req *Request | 请求对象 | 就算没有接收参数也要定义,因为请求结构体中不仅仅包含请求参数的定义,也包含了接口的请求定义。 |
res *Response | 返回对象 | 就算没有返回参数也要定义,因为返回结构体中不仅仅包含返回参数的定义,也可以包含接口返回定义。 |
err error | 错误对象 | Server 通过该参数判断接口执行成功或失败。 |
请求/返回结构体
路由统一注册
Group.Bind
方法
我们推荐使用对象化的方式来管理所有路由方法,并通过分组路由的Bind
方法执行统一注册。需要注意的是,在规范化路由方式下,路由地址以及请求方式将由请求结构体在g.Meta
元数据对象中通过标签定义,通过分组路由可以定义分组下的所有路由前缀。
Image Added
BindHandler
方法
我们也可以通过基础的BindHandler
方法来注册规范路由,但是该方法只能注册一个路由函数。使用示例:
Code Block | ||
---|---|---|
| ||
s := g.Server()
s.BindHandler("/user/{uid}", func(ctx context.Context, req *SaveReq) (res *SaveRes, err error) {
// ...
}) |
规范参数结构
在规范化路由注册中,非常重要的是请求/返回参数结构体的定义,在该结构体不仅仅包含了输入参数的定义,也包含了接口的定义,特别是路由地址、请求方法、接口描述等信息。通过结构体方式的数据结构参数维护,更有利于更丰富的接口能力扩展、团队间的接口交互、长期的接口维护、自动化的接口文档生成。
在规范化路由注册中,非常重要的是请求/返回结构体的定义,在该结构体不仅仅包含了输入参数的定义,也包含了接口的定义,特别是路由地址、请求方法、接口描述等信息。为保证命名规范化,输入数据结构以XxxReq
方式命名,输出数据结构以XxxRes
方式命名。即便输入或者输出参数为空,也需要定义相应的数据结构,这样的目的一个是便于后续扩展,另一个是便于接口信息的管理。关于结构体中涉及到OpenAPIv3
协议的标签介绍请查看后续章节。
Tip |
---|
请求参数自动转换到请求数据结构,字段映射转换不区分大小写,也会自动忽略特殊字符。 |
数据校验
请求结构体在进入API接口执行前将会被自动执行校验,如果其中一条规则校验失败,那么将终止后续规则的校验。校验功能使用的是框架统一的校验组件,具体请参考:数据校验
数据返回
输入数据校验
请求结构体在进入API
接口执行前将会被自动执行校验,如果其中一条规则校验失败,那么将终止后续规则的校验(自动使用了bail
校验修饰规则)。校验功能使用的是框架统一的校验组件,具体请参考:数据校验
Note |
---|
需要特别注意:如果参数校验存在多条校验规则,并且规则中存在 |
统一返回中间件
接口的数据返回处理需要设置统一的后置中间件,当然也可以使用Server
默认提供的数据返回中间件。开发者自定义中间件时可以参考Server
默认提供的中间件MiddlewareHandlerResponse
。
这里顺便提一下,在自定义返回中间件时一个重要的方法:接口的数据返回处理需要设置统一的后置中间件,当然也可以使用Server
默认提供的数据返回中间件。开发者自定义中间件时可以参考Server
默认提供的中间件。注意其中的一个重要的方法:
Code Block | ||
---|---|---|
| ||
// GetHandlerResponse retrieves and returns the handler response object and its error. // return type handlerResponse struct { // Object interface{} // Error error // } func (r *Request) GetHandlerResponse() interface{} |
通过后置中间件执行时通过请求对象的GetHandlerResponse
方法获取当前业务执行的结果,并根据需要做相应处理。
路由注册
我们推荐使用对象化的方式来管理所有路由方法,并通过分组路由的Bind
方法执行统一注册。
需要注意的是,在规范化路由方式下,路由地址以及请求方式将由请求结构体在g.Meta
中定义,通过分组路由可以定义分组下的所有路由前缀。
扩展介绍
OpenAPIv3
协议
Server
组件自动生成的接口文档使用的是最新的OpenAPIv3
协议。更多介绍请参考章节:接口文档
Ctx
中的Request
对象
我们可以通过RequestFromCtx/g.RequestFromCtx
方法从ctx
中获取Request
对象。
方法定义:
Code Block | ||
---|---|---|
| ||
func RequestFromCtx(ctx context.Context) *Request |
使用示例:
Code Block | ||
---|---|---|
| ||
func (c *cHello) Hello(ctx context.Context, req *apiv1.HelloReq) (res *apiv1.HelloRes, err error) {
g.RequestFromCtx(ctx).Response.Writeln("Hello World!")
return
} |
Panel | ||
---|---|---|
| ||
|