93 lines
4.4 KiB
Markdown
93 lines
4.4 KiB
Markdown
# 新增 HTTP 接口流程
|
||
|
||
项目 `controller` 定义于 `backend/app/http/[module_name]/[controller].go` 文件中。 每个 `controller` 负责处理一组相关的 HTTP 请求。 例如,`backend/app/http/super/tenant.go` 负责处理与租户相关的请求。
|
||
|
||
## 新增接口步骤
|
||
|
||
1. 在 `controller` 中新增方法以处理特定的 HTTP 请求。 例如,在 `tenant.go` 新增一个 `list` 方法来处理列出租户的请求。
|
||
2. 定义相关 `swagger` 注解以生成 API 文档。 这些注解通常位于方法上方,描述了请求路径、参数和响应格式。
|
||
3. 在模块 `dto/`(数据传输对象)目录中定义请求和响应的数据结构, 以确保数据的一致性和类型安全。
|
||
4. 运行 `atomctl gen route` 生成路由文件,确保新接口被正确注册。
|
||
5. 运行 `atomctl gen provider` 生成路由文件,确保新接口被正确注册。
|
||
|
||
## 接口定义示例:
|
||
|
||
1. 实现需要返回数据的接口。
|
||
|
||
```go
|
||
func (*tenant) list(ctx fiber.Ctx, filter *dto.TenantFilter) (*requests.Pager, error) {
|
||
return nil,nil
|
||
}
|
||
```
|
||
|
||
2. 实现不需要返回数据的接口
|
||
|
||
```go
|
||
func (*tenant) update(ctx fiber.Ctx, tenantID int64, form *dto.TenantExpireUpdateForm) error {
|
||
return nil
|
||
}
|
||
```
|
||
|
||
## swagger 注解说明
|
||
|
||
- **@Summary**: 接口的简要描述。
|
||
- **@Description**: 接口的详细描述。
|
||
- **@Tags**: 接口所属的分类标签。
|
||
- **@Accept**: 接口接受的数据格式。通常为 `json`
|
||
- **@Produce**: 接口返回的数据格式。通常为 `json`
|
||
- **@Param**: 定义接口的参数,包括参数名称、数据来源位置、数据类型、是否必须、和描述。如:`// @Param form body dto.LoginForm true "form"`
|
||
- **@Success**: 定义接口成功时的响应格式。如:
|
||
- 返回分页列表 `// @Success 200 {object} requests.Pager{items=dto.Item}`
|
||
- 直接返回对象 `// @Success 200 {object} dto.Item`
|
||
- 返回数据对象列表 `// @Success 200 {array} dto.Item`
|
||
- **@Router**: 定义接口的路由信息,包括路径和请求方法。如:`// @Router /super/tenants [get|post|put|delete|patch]`, 如果需要定义 path 参数,使用 `:paramName` 语法表示,如:`/super/tenants/:tenantID`
|
||
- **@Bind**: 定义参数绑定方式,格式: `@Bind <paramName> <position> [key(<key>)] [model(<field>|<model>[:<field>])]`
|
||
- `paramName` 与方法参数名一致(大小写敏感)
|
||
- `position`:`path`、`query`、`body`、`header`、`cookie`、`local`、`file`
|
||
- 可选:
|
||
- `key()` 覆盖默认键名;
|
||
- `model()` 详见“模型绑定”。
|
||
|
||
### 参数绑定
|
||
|
||
- query:标量用 `QueryParam[T]("key")`,非标量用 `Query[T]("key")`
|
||
- path:标量用 `PathParam[T]("key")`,非标量用 `Path[T]("key")`
|
||
- 若使用 `model()`(仅在 path 有效),会按字段值查询并绑定为 `T`,详见下文
|
||
- header:`Header[T]("key")`
|
||
- body:`Body[T]("key")`
|
||
- cookie:`string` 用 `CookieParam("key")`,其他用 `Cookie[T]("key")`
|
||
- file:`File[multipart.FileHeader]("key")`
|
||
- local:`Local[T]("key")`
|
||
|
||
说明:
|
||
|
||
- 标量类型集合:`string`、`int`、`int32`、`int64`、`float32`、`float64`、`bool`
|
||
- `key` 默认等于 `paramName`;设置 `key(...)` 后以其为准
|
||
- `file` 使用固定类型 `multipart.FileHeader`
|
||
|
||
### 类型与指针处理
|
||
|
||
- 支持 `T`、`*T`、`pkg.T`、`*pkg.T`;会正确收集选择子表达式对应 import
|
||
- 忽略结尾为 `Context` 或 `Ctx` 的参数(框架上下文)
|
||
- 指针处理:除 `local` 外会去掉前导 `*` 作为泛型实参;`local` 保留指针(便于写回)
|
||
|
||
### 模型绑定
|
||
|
||
当 `@Bind ... model(...)` 配合 `position=path` 使用时,将根据路径参数值查询模型并绑定为方法参数类型的实例(`T` 来自方法参数)。
|
||
|
||
- 语法:
|
||
- 仅字段:`model(id)`(推荐)
|
||
- 指定字段与类型:`model(id:int)`、`model(code:string)`(用于非字符串路径参数)
|
||
- 指定类型与字段:`model(pkg.Type:field)` 或 `model(pkg.Type)`(字段缺省为 `id`)
|
||
- 行为:
|
||
- 生成的绑定器会按给定字段构造查询条件并返回首条记录
|
||
- 自动注入 import:`field "go.ipao.vip/gen/field"`,用于构造字段条件表达式
|
||
|
||
示例:
|
||
|
||
```go
|
||
// @Router /users/:id [get]
|
||
// @Bind user path key(id) model(id)
|
||
func (uc *UserController) Show(ctx context.Context, user *models.User) (*UserDTO, error)
|
||
```
|