使用 Swagger 为 Symfony API 编写文档
API
昂首阔步
Web API 正成为热门趋势!
它们现在无处不在:它们为 JavaScript 单应用页面提供数据,它们允许开发人员管理 Elasticsearch 实例,它们用于将单体应用解耦为微服务……
由于 API 在现代 Web 应用中被广泛使用,我们可以看到 API 工具也得到了极大的升级。自动化 API 文档系统、API 客户端 SDK、易于使用的 REST 客户端……
我想分享一些我今年学到的很棒的工具组合技巧。
这篇文章将向您展示如何将一些工具组合在一起,以构建一个 PHP API:
- 使用 Swagger 编写准确的 HTML 文档
- 使用 Jane 的 PHP API 客户端 SDK
- 使用 Behat 进行 API 测试
我把帖子分成两部分,因为它太长了。
API
在这个例子中,我使用了一个简单的Symfony REST API 来处理电影数据库。
它有 3 个端点:
GET /v1/movies从数据库中获取电影,该函数接受一些参数:dir(排序方向,“asc”或“desc”)、page(用于分页)和 sort(选择要排序的字段)POST /v1/movie将新电影注册到数据库中DELETE /v1/movie/{id}从数据库中删除现有电影
DELETE 端点是软删除:记录被标记为已删除,但并未真正删除。
该 API 使用 Symfony 3.1 构建,数据库采用 DoctrineORM 管理,并使用了 FOSRestBundle 库。这没什么特别的,Symfony 开发人员会发现这非常标准:
你可以在这里查看代码。
昂首阔步
有趣的部分来了。API已经构建并测试完毕,现在我希望其他开发者能够使用它(例如,用来构建一个炫酷的JS前端)。
这些开发者会问我“文档在哪里?”,因为他们无法猜到 API 的工作原理。
我不想自己编写这份文档,因为我是一名开发人员,我喜欢自动化一切(尤其是那些枯燥乏味的任务),而且我也不想每次修改 API 时都更新它。所以我希望它能从代码中自动生成。
如果我能根据代码生成文档,那么每次修改代码时,文档也会随之更新。这样就不会再出现文档过时和参数拼写错误的问题了。
构建自动化 HTML API 文档的方法有很多种。对于 Symfony 应用,官方文档会重定向到NelmioApiDocBundle,它易于使用且高效。它会解析一些应用配置,并要求你为无法自动推断的内容添加注释。然后,它会生成一份优秀的 HTML 文档,例如:
我选择不使用它,而是为我的 API 生成一个 Swagger 文件。Swagger 是一种标准的 API JSON 规范格式,它定义了如何在 JSON 文件中描述 API。它的优点在于,许多 API 工具都支持这种格式,因此,拥有一个关于 API 的 Swagger 文件可以让您轻松地使用所有这些工具。
例如,
- SwaggerUI允许开发人员根据 Swagger 文件可视化 API 并与之交互。
- StopLight.io可以根据您的 Swagger 文件构建文档门户。
- Postman可以使用 Swagger 文件生成请求体和模板,方便您调用 API。
对 API 进行注释
因此,我需要生成一个描述我的 API 的 Swagger 文件。我首先尝试使用NelmioApiDocBundle 的Swagger 选项,它允许将 API 描述导出为 Swagger 文件。然而,生成的文件使用的是 Swagger v1.2 规范,而我稍后将在本文中使用的工具需要 Swagger v2 文件。
虽然有像api-spec-converter这样的工具可以将 Swagger v1 文件转换为 Swagger v2 文件,但我因为这种转换遇到了很多问题,所以我决定直接使用 v2 文件。
我使用swagger-php项目为我的 Symfony API 添加注解,这些注解可以被解析并生成所需的文件。基本上,你需要为你的控制器以及所使用的模型(请求体和响应体)添加注解。
例如,以下是描述 GET 端点所需的注解:
/**
* @SWG\Get(
* path="/movies",
* summary="Get movies",
* description="Get movies",
* operationId="getMovies",
* produces={"application/json"},
* @SWG\Parameter(
* name="order",
* in="query",
* description="Order criterion",
* type="string",
* ),
* @SWG\Parameter(
* name="dir",
* in="query",
* description="Sort criterion",
* type="string",
* ),
* @SWG\Parameter(
* name="page",
* in="query",
* description="Page number",
* type="integer",
* ),
* @SWG\Response(
* response=200,
* description="Success",
* @SWG\Schema(ref="#/definitions/MoviesViewDTO"),
* )
* )
*/
public function getMoviesAction(Request $request)
语法非常简单明了,您只需描述您的端点接受哪些参数/请求体以及它返回什么即可。
对于请求和响应主体,如果提供了一些注解,Swagger-php 可以分析 PHP 模型以提取其结构:
/**
* @SWG\Definition()
*/
class MoviesViewDTO
{
/**
* @var int
*
* @SWG\Property()
*/
public $total;
...
因此,如果您接受并返回 DTO(又称 POPO),则可以轻松提取其结构并将其写入 Swagger 文件。
完成路由和模型注解后,即可在项目上运行 Swagger PHP 二进制文件,它会生成 Swagger 文件。文件内容如下所示:
{
"swagger": "2.0",
"info": {
"title": "Movies API",
"version": "1.0"
},
"basePath": "/v1",
"schemes": [
"http"
],
"paths": {
"/movies": {
"get": {
"summary": "Get movies",
"description": "Get movies",
"operationId": "getMovies",
"produces": [
"application/json"
],
"parameters": [
{
"name": "order",
"in": "query",
"description": "Order criterion",
"type": "string"
},
{
"name": "dir",
"in": "query",
"description": "Sort criterion",
"type": "string"
},
...
}
完整文件可在GitHub上获取。
恭喜:Swagger 文件已编写完成!
使用 Swagger 文件
HTML 文档
现在我们有了这个文件,就可以使用swagger-editor来查看 HTML 文档的样式了。我们只需将 JSON 内容复制到编辑器中,它就会渲染出 HTML 文档:
然后可以将文档导出并托管在网络服务器上,以便开发人员随时查看。如果您使用 SwaggerUI,它甚至还提供沙箱功能,让您可以执行真实的 HTTP 请求,从而实时查看 API 的运行情况!
与 REST 客户端一起使用
我们还可以将其输入到Postman中,以获取预配置的 REST 客户端来与 API 进行交互:
请求已预先配置,现在从客户端执行 HTTP 请求非常容易。这对于新开发人员加入团队尤其有用,他只需几秒钟即可准备好开发/调试工具!
将其用作团队协作工具
如果贵公司有一个后端团队负责开发 API,还有一个前端团队负责使用该 API,那么他们需要讨论并就 API 的行为达成一致。
使用 Swagger 规范非常有用:在开发新功能时,两个团队可以共同协作,修改 Swagger 文件,并确认更新后的文件符合该功能所需的 API 规范。之后,后端团队可以开始根据 Swagger 规范进行实现,而前端团队则可以立即着手开发,因为他们已经了解 API 的接收和返回值。一些工具甚至可以使用 Swagger 文件生成模拟 API,以便在后端团队完成工作之前,为前端团队提供一个可供使用的模拟 API。
Jane & Behat
我们下篇帖子第二部分见:)
文章来源:https://dev.to/matks/use-swagger-to-document-a-symfony-api-790





