2.12. API 文档

优质
小牛编辑
141浏览
2023-12-01

API 的文档与 API 的功能一样重要。为了使文档处理过程变得更加简单, dingo 提供了在 API 的 Controller 中添加注释之后通过 artisan 命令行组件生成文档。

Artisan 命令

你可以使用 api:docs 命令生成文档。这个命令两个必须的参数,一个是文档的名字另一个是文档的生成版本号。

详细的使用方法请看 Commands

资源

控制器通常可以看作为一种资源。资源可能包含许多由 HTTP 动词表示的动作。

定义一个资源我们可以使用 @Resource 注释:

/**
 * @Resource("Users")
 */
class UserController extends Controller
{

}

第一个参数给定了资源的标识或资源的名称。我们也可以给这个资源一个基础的 URI 。

/**
 * @Resource("Users", uri="/users")
 */
class UserController extends Controller
{

}

你也可以在注释之前给资源一段描述。

/**
 * 用户资源标识
 *
 * @Resource("Users", uri="/users")
 */
class UserController extends Controller
{

}

行为

控制器中的一个行为可以被看作路由的一个方法。

你可以使用 PHPDoc 的简短描述来描述你的行为。

/**
 * 显示所有用户
 *
 * 使用 JSON 返回所有注册用户
 */
public function index()
{

}

@Get, @Post, @Put, @Patch, @Delete

每一个行为都可以看作是一个 HTTP 动作。你必须提供一个 URI 作为注释的第一个参数。

/**
 * 显示所有用户
 *
 * 使用 JSON 返回所有注册用户
 *
 * @Get("/")
 */
public function index()
{

}

@Versions

一个行为可能在多个 API 版本种可用。生成文档时,此注释用于确定生成之后将包含哪些行为。

/**
 * 显示所有用户
 *
 * 使用 JSON 返回所有注册用户
 *
 * @Get("/")
 * @Versions({"v1"})
 */
public function index()
{

}

@Request

一个行为应该定义一个可以被执行的请求,这个请求将会返回一个成功或者失败的响应。

一个请求应该包含一个主体内容。不同的请求类型 body 的内容是不同的。对于 POST 请求你可以使用字符串,但是您还需要设置 content type

/**
 * 用户注册
 *
 * 使用 username 和 password 注册一个新用户
 *
 * @Post("/")
 * @Versions({"v1"})
 * @Request("username=foo&password=bar", contentType="application/x-www-form-urlencoded")
 */
public function store()
{

}

如果你发送 JSON 可以使用注释数组,它将自动被编码成 JSON 字符串。Content Type 将默认设置为 application/json

/**
 * 用户注册
 *
 * 使用 username 和 password 注册一个新用户
 *
 * @Post("/")
 * @Versions({"v1"})
 * @Request({"username": "foo", "password": "bar"})
 */
public function store()
{

}

您可以包含额外的 Headers

/**
 * 用户注册
 *
 * 使用 username 和 password 注册一个新用户
 *
 * @Post("/")
 * @Versions({"v1"})
 * @Request({"username": "foo", "password": "bar"}, headers={"X-Custom": "FooBar"})
 */
public function store()
{

}

如果行为的多个请求的响应是不同的,则必须标识该请求。

/**
 * 用户注册
 *
 * 使用 username 和 password 注册一个新用户
 *
 * @Post("/")
 * @Versions({"v1"})
 * @Request({"username": "foo", "password": "bar"}, identifier="A")
 */
public function store()
{

}

@Response

@Response 定义在 @Request 后边,它定义了状态码、响应内容类型、响应体以及响应头。

与请求一样,响应体可以是字符串(确保连同 contentType 一起改动),也可以是注解数组,它会自动进行 JSON 编码。

/**
 * 注册用户
 *
 * 使用 `username` 和 `password` 注册用户。
 *
 * @Post("/")
 * @Versions({"v1"})
 * @Request({"username": "foo", "password": "bar"})
 * @Response(200, body={"id": 10, "username": "foo"})
 */
public function store()
{

}

也可以像请求一样包含头信息。

@Transaction

事物允许你定义多个请求和多个响应。 响应必须跟在请求后边,当然,单个请求后边可以有多个响应。

/**
 * 注册用户
 *
 * 使用 `username` 和 `password` 注册用户。
 *
 * @Post("/")
 * @Versions({"v1"})
 * @Transaction({
 *      @Request({"username": "foo", "password": "bar"}),
 *      @Response(200, body={"id": 10, "username": "foo"}),
 *      @Response(422, body={"error": {"username": {"Username is already taken."}}})
 * })
 */
public function store()
{

}

@Parameters

如果你的 URI 包含查询字符串参数,那么你可以在资源级别或动作级别定义它们。如果在资源级别定义了参数,那么你需要为每个动作或资源定义它。

/**
 * Show all users
 *
 * Get a JSON representation of all the registered users.
 *
 * @Get("/{?page,limit}")
 * @Versions({"v1"})
 * @Parameters({
 *      @Parameter("page", description="The page of results to view.", default=1),
 *      @Parameter("limit", description="The amount of results per page.", default=10)
 * })
 */
public function index()
{

}

你还可以用 type 来定义类型,用 required 定义是否为必须项。

/**
 * @Parameters({
 *      @Parameter("example", type="integer", required=true, description="This is an example.", default=1)
 * })
 */
public function index()
{

}