api 语法

概述

api 是 go-zero 自研的领域特性语言(下文称 api 语言 或 api 描述语言),旨在实现人性化的基础描述语言,作为生成 HTTP 服务最基本的描述语言。

api 领域特性语言包含语法版本,info 块,结构体声明,服务描述等几大块语法组成,其中结构体和 Golang 结构体 语法几乎一样,只是移出了 struct 关键字。

快速入门

本次仅以 demo 形式快速介绍 api 文件的写法,更详细的写法示例可参考 《API 定义完整示例》,详细 api 语法规范可参考 《API 规范》

示例 1. 编写最简单的 ping 路由服务

  1. syntax = "v1"
  2. // 定义 HTTP 服务
  3. service foo {
  4. get /ping
  5. }

示例 2. 编写一个登录接口 api 文件

  1. syntax = "v1"
  2. type (
  3. // 定义登录接口的请求体
  4. LoginReq {
  5. Username string `json:"username"`
  6. Password string `json:"password"`
  7. }
  8. // 定义登录接口的响应体
  9. LoginResp {
  10. Id int64 `json:"id"`
  11. Name string `json:"name"`
  12. Token string `json:"token"`
  13. ExpireAt string `json:"expireAt"`
  14. }
  15. )
  16. // 定义 HTTP 服务
  17. // 微服务名称为 user,生成的代码目录和配置文件将和 user 值相关
  18. service user {
  19. // 定义 http.HandleFunc 转换的 go 文件名称及方法
  20. @handler Login
  21. // 定义接口
  22. // 请求方法为 post
  23. // 路由为 /user/login
  24. // 请求体为 LoginReq
  25. // 响应体为 LoginResp,响应体必须有 returns 关键字修饰
  26. post /user/login (LoginReq) returns (LoginResp)
  27. }

示例 3. 编写简单的用户服务 api 文件

  1. syntax = "v1"
  2. type (
  3. // 定义登录接口的 json 请求体
  4. LoginReq {
  5. Username string `json:"username"`
  6. Password string `json:"password"`
  7. }
  8. // 定义登录接口的 json 响应体
  9. LoginResp {
  10. Id int64 `json:"id"`
  11. Name string `json:"name"`
  12. Token string `json:"token"`
  13. ExpireAt string `json:"expireAt"`
  14. }
  15. )
  16. type (
  17. // 定义获取用户信息的 json 请求体
  18. GetUserInfoReq {
  19. Id int64 `json:"id"`
  20. }
  21. // 定义获取用户信息的 json 响应体
  22. GetUserInfoResp {
  23. Id int64 `json:"id"`
  24. Name string `json:"name"`
  25. Desc string `json:"desc"`
  26. }
  27. // 定义更新用户信息的 json 请求体
  28. UpdateUserInfoReq {
  29. Id int64 `json:"id"`
  30. Name string `json:"name"`
  31. Desc string `json:"desc"`
  32. }
  33. )
  34. // 定义 HTTP 服务
  35. // @server 语法块主要用于控制对 HTTP 服务生成时 meta 信息,目前支持功能有:
  36. // 1. 路由分组
  37. // 2. 中间件声明
  38. // 3. 路由前缀
  39. // 4. 超时配置
  40. // 5. jwt 鉴权开关
  41. // 所有声明仅对当前 service 中的路由有效
  42. @server (
  43. // 代表当前 service 代码块下的路由生成代码时都会被放到 login 目录下
  44. group: login
  45. // 定义路由前缀为 "/v1"
  46. prefix: /v1
  47. )
  48. // 微服务名称为 user,生成的代码目录和配置文件将和 user 值相关
  49. service user {
  50. // 定义 http.HandleFunc 转换的 go 文件名称及方法,每个接口都会跟一个 handler
  51. @handler login
  52. // 定义接口
  53. // 请求方法为 post
  54. // 路由为 /user/login
  55. // 请求体为 LoginReq
  56. // 响应体为 LoginResp,响应体必须有 returns 关键字修饰
  57. post /user/login (LoginReq) returns (LoginResp)
  58. }
  59. // @server 语法块主要用于控制对 HTTP 服务生成时 meta 信息,目前支持功能有:
  60. // 1. 路由分组
  61. // 2. 中间件声明
  62. // 3. 路由前缀
  63. // 4. 超时配置
  64. // 5. jwt 鉴权开关
  65. // 所有声明仅对当前 service 中的路由有效
  66. @server (
  67. // 代表当前 service 代码块下的所有路由均需要 jwt 鉴权
  68. // goctl 生成代码时会将当前 service 代码块下的接口
  69. // 信息添加上 jwt 相关代码,Auth 值为 jwt 密钥,过期
  70. // 等信息配置的 golang 结构体名称
  71. jwt: Auth
  72. // 代表当前 service 代码块下的路由生成代码时都会被放到 user 目录下
  73. group: user
  74. // 定义路由前缀为 "/v1"
  75. prefix: /v1
  76. )
  77. // 注意,定义多个 service 代码块时,服务名称必须一致,因此这里的服务名称必须
  78. // 和上文的 service 名称一样,为 user 服务。
  79. service user {
  80. // 定义 http.HandleFunc 转换的 go 文件名称及方法,每个接口都会跟一个 handler
  81. @handler getUserInfo
  82. // 定义接口
  83. // 请求方法为 post
  84. // 路由为 /user/info
  85. // 请求体为 GetUserInfoReq
  86. // 响应体为 GetUserInfoResp,响应体必须有 returns 关键字修饰
  87. post /user/info (GetUserInfoReq) returns (GetUserInfoResp)
  88. // 定义 http.HandleFunc 转换的 go 文件名称及方法,每个接口都会跟一个 handler
  89. @handler updateUserInfo
  90. // 定义接口
  91. // 请求方法为 post
  92. // 路由为 /user/info/update
  93. // 请求体为 UpdateUserInfoReq
  94. // 由于不需要响应体,因此可以忽略不写
  95. post /user/info/update (UpdateUserInfoReq)
  96. }

示例 4. 编写带有中间件的 api 服务

  1. syntax = "v1"
  2. type GetUserInfoReq {
  3. Id int64 `json:"id"`
  4. }
  5. type GetUserInfoResp {
  6. Id int64 `json:"id"`
  7. Name string `json:"name"`
  8. Desc string `json:"desc"`
  9. }
  10. // @server 语法块主要用于控制对 HTTP 服务生成时 meta 信息,目前支持功能有:
  11. // 1. 路由分组
  12. // 2. 中间件声明
  13. // 3. 路由前缀
  14. // 4. 超时配置
  15. // 5. jwt 鉴权开关
  16. // 所有声明仅对当前 service 中的路由有效
  17. @server (
  18. // 定义一个鉴权控制的中间件,多个中间件以英文逗号,分割,如 Middleware1,Middleware2,中间件按声明顺序执行
  19. middleware: AuthInterceptor
  20. )
  21. // 定义一个名称为 user 的服务
  22. service user {
  23. // 定义 http.HandleFunc 转换的 go 文件名称及方法,每个接口都会跟一个 handler
  24. @handler getUserInfo
  25. // 定义接口
  26. // 请求方法为 post
  27. // 路由为 /user/info
  28. // 请求体为 GetUserInfoReq
  29. // 响应体为 GetUserInfoResp,响应体必须有 returns 关键字修饰
  30. post /user/info (GetUserInfoReq) returns (GetUserInfoResp)
  31. }

示例 5. 编写带有超时配置的 api 服务

  1. syntax = "v1"
  2. type GetUserInfoReq {
  3. Id int64 `json:"id"`
  4. }
  5. type GetUserInfoResp {
  6. Id int64 `json:"id"`
  7. Name string `json:"name"`
  8. Desc string `json:"desc"`
  9. }
  10. // @server 语法块主要用于控制对 HTTP 服务生成时 meta 信息,目前支持功能有:
  11. // 1. 路由分组
  12. // 2. 中间件声明
  13. // 3. 路由前缀
  14. // 4. 超时配置
  15. // 5. jwt 鉴权开关
  16. // 所有声明仅对当前 service 中的路由有效
  17. @server (
  18. // 定义一个超时时长为 3 秒的超时配置,这里可填写为 time.Duration 的字符串形式,详情可参考
  19. // https://pkg.go.dev/time#Duration.String
  20. timeout: 3s
  21. )
  22. // 定义一个名称为 user 的服务
  23. service user {
  24. // 定义 http.HandleFunc 转换的 go 文件名称及方法,每个接口都会跟一个 handler
  25. @handler getUserInfo
  26. // 定义接口
  27. // 请求方法为 post
  28. // 路由为 /user/info
  29. // 请求体为 GetUserInfoReq
  30. // 响应体为 GetUserInfoResp,响应体必须有 returns 关键字修饰
  31. post /user/info (GetUserInfoReq) returns (GetUserInfoResp)
  32. }

示例 6. 结构体引用

  1. syntax = "v1"
  2. type Base {
  3. Code int `json:"code"`
  4. Msg string `json:"msg"`
  5. }
  6. type UserInfo {
  7. Id int64 `json:"id"`
  8. Name string `json:"name"`
  9. Desc string `json:"desc"`
  10. }
  11. type GetUserInfoReq {
  12. Id int64 `json:"id"`
  13. }
  14. type GetUserInfoResp {
  15. // api 支持匿名结构体嵌套,也支持结构体引用
  16. Base
  17. Data UserInfo `json:"data"`
  18. }
  19. // 定义一个名称为 user 的服务
  20. service user {
  21. // 定义 http.HandleFunc 转换的 go 文件名称及方法,每个接口都会跟一个 handler
  22. @handler getUserInfo
  23. // 定义接口
  24. // 请求方法为 post
  25. // 路由为 /user/info
  26. // 请求体为 GetUserInfoReq
  27. // 响应体为 GetUserInfoResp,响应体必须有 returns 关键字修饰
  28. post /user/info (GetUserInfoReq) returns (GetUserInfoResp)
  29. }

示例 7. 控制最大请求体控制的 api 服务

  1. syntax = "v1"
  2. type GetUserInfoReq {
  3. Id int64 `json:"id"`
  4. }
  5. type GetUserInfoResp {
  6. Id int64 `json:"id"`
  7. Name string `json:"name"`
  8. Desc string `json:"desc"`
  9. }
  10. // @server 语法块主要用于控制对 HTTP 服务生成时 meta 信息,目前支持功能有:
  11. // 1. 路由分组
  12. // 2. 中间件声明
  13. // 3. 路由前缀
  14. // 4. 超时配置
  15. // 5. jwt 鉴权开关
  16. // 所有声明仅对当前 service 中的路由有效
  17. @server (
  18. // 定义一个请求体限制在 1MB 以内的请求,goctl >= 1.5.0 版本支持
  19. maxBytes: 1024
  20. )
  21. // 定义一个名称为 user 的服务
  22. service user {
  23. // 定义 http.HandleFunc 转换的 go 文件名称及方法,每个接口都会跟一个 handler
  24. @handler getUserInfo
  25. // 定义接口
  26. // 请求方法为 post
  27. // 路由为 /user/info
  28. // 请求体为 GetUserInfoReq
  29. // 响应体为 GetUserInfoResp,响应体必须有 returns 关键字修饰
  30. post /user/info (GetUserInfoReq) returns (GetUserInfoResp)
  31. }

参考文献