使用 Swagger 文档化和定义 RESTful API

大部分 Web 应用程序都支持 RESTful API,但不同于 SOAP API——REST API 依赖于 HTTP 方法,缺少与 Web 服务描述语言(Web Services Description Language,WSDL)类似的语言来定义使用者与提供者之间的请求和响应结构。由于没有充分的合同服务,许多 REST API 提供者使用 Microsoft Word 文档或维基页面来记录 API 用法。这些格式使协作和文档版本控制变得很困难,尤其对于有许多 API 或资源的应用程序,或者在 API 采用迭代式开发方式时。这些文档类型在集成到自动化测试应用程序中时变得更难。

开源 Swagger 框架帮助 API 使用者和开发人员纠正了这些问题。该框架为创建 JSON 或 YAML(JSON 的一个人性化的超集)格式的 RESTful API 文档提供了 OpenAPI 规范(以前称为 Swagger 规范)。Swagger 文档可由各种编程语言处理,可在软件开发周期中签入源代码控制系统中,以便进行版本管理。

但是 Swagger 本身也有不足之处。当我们使用该框架记录自己的 API 时,会发现我们的文档需求与 Swagger 的基本功能之间存在空白。我们将介绍我们在文档化过程中遇到的挑战,并展示如何通过以下方法解决它们:

  • 实现 Swagger 扩展
  • 简化 Swagger 的功能来聚合文档
  • 创建一个输出 Swagger 文档为 HTML 页面的工具

我们开发的解决方案可通过下载获得(参见“下载”)。您可以修改我们的示例,以便使用 Swagger 为您自己的 RESTful API 创建文档,并(使用您在本文中学到的技术)创建您自己的 Swagger 定制化。

使用 Swagger

一些 Swagger 编辑工具可帮助您轻松地创建 API 文档,确保它们遵守 OpenAPI 规范。举例而言,通过使用 Swagger Editor,您可以创建或导入 API 文档,并在一个交互式环境中浏览它。右侧的显示窗格显示了格式化的文档,反映了您在左侧窗格中的代码编辑器中执行的更改。代码编辑器指出了所有格式错误。您可以展开和折叠每个窗格。

以下是您导入 leads.yaml 定义后的 Swagger Editor UI 外观:

放在屏幕截图上的红色箭头表示基于 OpenAPI 规范的 leads.yaml 文件中的 post: 和 get: 定义,与预览文档中 POST 和 GET API 的文档之间的对应关系。

如果使用 Eclipse 作为 IDE,您可以使用 YEdit,它会检查并突出显示 YAML 语法,还会提供编辑和格式化功能。

扩展 Swagger

现有的工具使编辑 Swagger API 文档变得很容易,但某些文档场景带来了一些挑战。以下这些是我们在使用 Swagger 记录自己的 API 文档时遇到的一些实际问题:

  • API 使用者需要获得特定于我们的 API 的信息,但 OpenAPI 规范不包含该信息的标准。
  • API 使用者需要请求和响应示例,但现有的编辑器无法包含它们。
  • 我们需要提供一个容易阅读的富文档,其中包含可供 API 使用者使用的示例,最好是采用在线 HTML 文档形式。

为了解决这些问题,我们根据 OpenAPI 规范创建了自己的属性、工具和模板。

扩展属性

您可以使用 x- 扩展属性来扩展 Swagger。以下是我们为自己的 API 专门定制的一些扩展,以及它们的用法示例:

以下属性用于 API 有效负载或响应字段:

  • x-sc-crud:记录一个 API 字段的有效创建、读取、更新和删除(CRUD)操作:


    1

    x-sc-crud:  [ read, update, create ]

  • x-sc-required:指示此字段需要哪些 CRUD 操作:

    1

    x-sc-required: [ create ]

  • x-sc-fieldmap:记录与指定的 API 字段关联的数据库表和 UI 字段:

    1

    2

    3

    x-sc-fieldmap:

      table: TASKS_RELATED_TO

      uifieldname: Related to

  • x-sc-enum:记录 API 字段的有效值。可以不使用静态值列表,而指定一个返回当前的可能值集合的 API。

    1

    2

    x-sc-enum:

      api: /leads/enum/alt_address_country

  • x-sc-comments:为 description 属性提供补充,用于捕获给定 API 字段的额外的临时信息:

    1

    2

    x-sc-comments:

      - readonly in UI, aka Domestic Buying Group or DB

下面的清单是 Lead 模块中的 lead_source API 字段的 YAML 定义中的 x-sc 属性的示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

lead_source:

  type: string

  maxLength: 100

  externalDocs:

    description: Lead Source // Current (0100) // Approved // op - Opportunity

    url: https://w3.ibm.com/standards/information/tmt/output/Approved/

    ibmww/op/bds/Opportunity_Management/Lead_Source.html

#

# lead_source value is returned when retrieving a lead,

# and you can set its value when creating or updating a Lead.

#

  x-sc-crud:  [ read, update, create ]

  

#

# The lead_source is a required field when creating a Lead.

#

  x-sc-required: [ create ]

  

#

# You can retrieve valid lead_source values from the

# /leads/enum/lead_source API.

#

  x-sc-enum:

    api: /leads/enum/lead_source

    AVL:

      dictionary_name: leads_lead_source_dom

    

  example: LinkedIn

    

#

# The value of lead_source is saved in the LEADS table.

# In UI, you can find lead_source under the "Lead Source" label.

#

  x-sc-fieldmap:

    table: LEADS

    uifieldname: Lead Source

以下属性扩展了 API 操作的描述:

  • x-sc-samples:记录示例。此属性包含对文档的示例小节的 JSON 引用列表:(参见“包含示例”小节了解更多信息)


    1

    2

    3

    x-sc-samples:

      - $ref: ‘#/x-sc-samples/leads-post-create-lead‘

      - $ref: ‘#/x-sc-samples/leads-post-create-lead-employeecnum‘

  • x-sc-APIm-plans:列出包含该操作的 IBM API Connect(以前称为 IBM API Management)计划。我们希望捕获特定于 API Manager 的信息:

    1

    2

    x-sc-APIm-plans:

      - salesconnect_leads_read

以下是 /leads API 端点的 HTTP POST 方法的 YAML 资源中的 x-sc 属性示例:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

paths:

     

  /leads:

    parameters:

      - $ref: ‘MASTER#/parameters/OAuthToken‘

      - $ref: ‘MASTER#/parameters/ContentType‘

      

    post:

      summary: create lead

      tags: [ leads ]

#

# Use the x-sc-APIm-plans property to specify that this endpoint

# is in APIm‘s salesconnect_leads_create plan.

#

      x-sc-APIm-plans:

        - salesconnect_leads_create

        

      description: |

        <p>API to create a lead.</p>

#

# Use the x-sc-samples property to refer to samples of the usage

# of the /leads API.

#

      x-sc-samples:

        - $ref: ‘#/x-sc-samples/leads-post-create-lead‘

        - $ref: ‘#/x-sc-samples/leads-post-create-lead-employeecnum‘

           

        

      parameters:

        - name: lead_definition

          in: body

          description: definition of lead to be created

          schema:

            $ref: ‘#/definitions/LeadObject‘

            

      responses:

        200:

          $ref: ‘#/responses/LeadObjectResponse‘

          

        422:

          description: |

         <p>scenarios</p>

         <ul>

         <li>missing required field</li>

         <li>invalid values for optional fields</li>

         <li>et cetera</li>

         </ul>

包含示例

尽管 Swagger 是一个定义 RESTful API 的强大工具,但它未提供用于包含 HTTP 请求和响应示例,或者用于为开发人员添加已编写文档的途径。

为了包含请求和响应示例,我们扩展了该规范,并再次使用了 YAML 来记录示例。我们将自己的示例放在一个分离的模式(schema)中,这样就不会让主要 API 文档过于复杂。

下面的 leads-post-create-lead 示例告诉使用者如何调用 /leads API 的 HTTP POST 方法,描述 URL、方法、头文件、URL 参数、输入(示例有效负载)和响应:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

x-sc-samples:

  leads-post-create-lead:

    title: Create a New lead

    description: |

      This sample creates a new lead, and assigns it to a user specified via sugar user id.

         

    method: POST

    url: https://w3-dev.api.ibm.com/sales/development/salesconnect/leads

      

      

    headers: |

      Content-Type: application/json

      Oauth-Token:  111e567a-7624-35f7-ed82-540f5a954312

      

      

    Parameters:  ?client_id={client_id}&client_secret={client_secret}

      

    Input: |

      {

        "created_by": "[email protected]",

        "assigned_user_id": "51449f9b-a68f-059c-ad06-5039325c53b2",

        "description": "2015-01-27 leads test",

        "first_name": "one",

        "last_name": "smith",

        "phone_mobile": "22-222-2222",

        ...

      }

      

      

    Response: |

      {

        "my_favorite": false,

        "following": false,

        "id": "a260acfb-5b3e-3f74-2392-54d92387fb80",

        "name": "one smith"

        ...

        "_module": "Leads"

      }

在 /leads API 部分的 HTTP POST 方法中,我们使用了扩展的属性 x-sc-samples 和对 x-sc-samples 模式中的示例代码 leads-post-create-lead 的 JSON 引用:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

paths:

     

  /leads:

    parameters:

      - $ref: ‘MASTER#/parameters/OAuthToken‘

      - $ref: ‘MASTER#/parameters/ContentType‘

      

    post:

      summary: create lead

      tags: [ leads ]

      x-sc-APIm-plans:

        - salesconnect_leads_create

        

      description: |

        <p>API to create a lead.</p>

#

# Use the x-sc-samples property to refer to samples of the usage

# of the /leads API.

#

      x-sc-samples:

        - $ref: ‘#/x-sc-samples/leads-post-create-lead‘

        - $ref: ‘#/x-sc-samples/leads-post-create-lead-employeecnum‘

        

        

      parameters:

        - name: lead_definition

          in: body

          description: definition of lead to be created

          schema:

            $ref: ‘#/definitions/LeadObject‘

            

      responses:

        200:

          $ref: ‘#/responses/LeadObjectResponse‘

          

        422:

          description: |

            <p>scenarios</li>

            <ul>

            <li>missing required field</li>

            <li> invalid values for optional fields</li>

            <li> et cetera</li>

            </ul>

将定义和示例放在一起

为了将所有模块定义和示例放在一起,我们使用了一个 MASTER.yaml 文件。此文件记录了逻辑信息,包括 Swagger 版本、API 版本、总体信息和提供该 API 的相对基础路径(relative base path)。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

swagger: ‘2.0‘

info:

  version: ‘3.4‘

  title:  Sales Connect API

#

#

  description: >

    This is the SalesConnect API.

    <p> There are several modules, each with different top level path.

    Most of the modules follow the same general pattern for operations and results,

    varying in the Sales Connect object that is manipulated.</p>

    <p>  The individual module descriptions show

    the particular operations and any module specific details.</p>

 

#

#

basePath: /sales/test/salesconnect

host: w3-dev.api.ibm.com

此外,MASTER.yaml 还包含包、共享对象和模板的注解。

通过在 MASTER.yaml 文件中定义 package(包)和 package sets(包集)属性,可以动态地生成内容。一个 package(包)定义了与给定模块相关的所有 YAML 文件,而 package set(包集)是对最终文档中的内容进行精细控制的包的集合。在我们的示例中, demo 和 default 包集分别从一组不同的文件中拉取内容。结合使用包和包集,我们可以轻松地将已发布模块与仍在开发中的模块分开。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

x-sc-master:   

  

  packages:

    bulk:

    - modules/bulk

    

#

# The oauth package contains 2 files:

#   - the modules/oauth.yaml file

#   - the samples/oauth-samples.yaml file

#   

    oauth:

    - modules/oauth

    - samples/oauth-samples

       

    calls:

    - modules/calls

    - samples/calls-samples

    

    collab:

    - modules/collab

    

    notes:

    - modules/notes

    - samples/notes-samples

    

    ...

    leads:

    - modules/leads

    - samples/leads-samples

    - samples/leadsTBD-samples

    ...

    

  package-sets:

  

#

# When generating a "default" document, our tool pulls

# content from files specified under the "oauth", "bulk",

# "calls", "collab" and "notes" packages.

#

    default:

      - oauth

      - bulk

      - calls     

      - collab

      - notes

     

#

# When generating a "demo" document, our tool pulls

# in a different set of files.

#

    demo:

      - oauth

      - notes

      - leads

共享对象

我们注意到,在实现过程中,反复提到了一些对象:多个 API 后端使用了相同的过滤器 URL 参数,多个 API 的 GET 方法返回了一组相同的基本字段,而且 API Manager 为不同的调用返回了相同的错误消息格式。为了减少冗余,我们使用 BasicObject 属性和 APImException 对象将这些元素提取到 MASTER.yaml 文件中,前者定义了所有 HTTP 方法 GET API 返回的基本字段,后者描述了从 API Manager 返回的错误结构。

使用模板

许多 API 的响应都遵循类似的模式,所以我们设计了模板来减少重复和支持变体。例如,当一个模块链接到另一个模块时,一些 API 的响应将包含来自二者的对象。为了适应这种情形,我们在 MASTER.yaml 文件中设计了一个 (OBJECT)Link(otherOBJECT)Response 模板:


1

2

3

4

5

6

7

8

9

10

11

(OBJECT)Link(otherOBJECT)Response:

    description: |

      Result of creating link from (OBJECT) to (otherOBJECT).

      The record contains the (OBJECT) and the <em>related_record</em> the (otherOBJECT) objects.

    schema:

      properties:

        record:

          $ref: ‘MASTER#/definitions/(OBJECT)‘

            

        related_record:

          $ref: ‘MASTER#/definitions/(otherOBJECT)‘

当记录一个将 Note 模块 (OBJECT=NoteObject) 链接到 Account 模块 (otherOBJECT=AccountObject) 的 API 的响应时,可以采用以下格式:


1

2

3

4

5

6

7

post:

  summary: Establish an accounts link to note using ccms id.

  description: Establish an accounts link to note using ccms id.

  responses:

    default:

      $ref: ‘MASTER?OBJECT=NoteObject&otherOBJECT=AccountObject#/responses/

(OBJECT)Link(otherOBJECT)Response‘

在我们的示例中,$ref 告诉该工具访问 MASTER.yaml 文件并在 responses 模式下查找(OBJECT)Link(otherOBJECT)Response 对象。实例化 JSON 引用之前,该工具将 OBJECT 变量替换为 NoteObject,将 otherOBJECT 替换为 AccountObject。最终,该模板被扩展为:


1

2

3

4

5

6

7

8

9

10

11

NoteObjectLinkAccountObjectResponse:

    description: |

      Result of creating link from NoteObject to AccountObject.

      The record contains the NoteObject and the <em>related_record</em> the AccountObject objects.

    schema:

      properties:

        record:

          $ref: ‘MASTER#/definitions/NoteObject‘

             

        related_record:

          $ref: ‘MASTER#/definitions/AccountObject‘

类似地,您可以通过将 OBJECT 和 otherOBJECT 设置为不同的值,使用此模板来记录将 Note 模块链接到 Opportunity 模块的 API 的响应:


1

2

3

4

5

6

7

8

9

post:

  summary: Link from note to opportunity.

  description: Link from note to opportunity.

  x-sc-APIm-plans: [ salesconnect_notes_create ]

  responses:

    default:

      $ref:

‘MASTER?OBJECT=NoteObject&otherOBJECT=OpportunityObject#/responses/

(OBJECT)Link(otherOBJECT)Response‘

将 YAML 文档转换为 HTML 页面

为了让 API 文档对用户更友好,我们实现了一个工具(swagger-to-html.php)来将 YAML 文档转换为静态 HTML。尽管可以使用现有工具从 Swagger 构建 HTML 文档,但我们决定创建自己的工具,以便可以添加对 x-sc-* 扩展的特殊处理功能。

该工具将会读入 MASTER.yaml 文件,合并所有必要的 YAML 文件,解析引用,然后输出一个 HTML 页面。该工具接受许多不同的参数,您可使用它们来自定义 HTML 文件的内容。例如,您可以为特定模块生成 HTML 文件,为特定包集生成 HTML 文件,或者仅为向 IBM API Management 应用程序注册的 API 生成 HTML 文件。

生成的 HTML 是单个文件,它使用 CSS 设置样式,使用 JavaScript 自动化各个部分的折叠、展开和导航功能。HTML 生成器工具会呈现通用 JSON 对象、JSON 模式定义,以及参数、响应、操作等的 Swagger 描述。

这是为 Lead 模块中的 lead_source 项生成的 HTML 页面(请参阅“扩展属性”部分的相应 YAML 文档):

这是来自 /leads API 端点的 HTTP POST 方法的 HTML 页面(请参阅“包含示例”部分的相应 YAML 文档):

幕后原理

这个 API-swagger.zip 文件(参见“下载”)演示了我们的 Swagger API 文档子集中针对 SalesConnect 系统中的三个模块的部分:OAuthLead 和 Note。这些 API 位于 /modules 目录中,相应的示例包含在 /samples 目录中。

要生成 HTML 页面:

  1. 安装必备软件(PHP 和 PHP YAML 扩展)。
  2. 使用 cd 命令转到 API-Swagger 目录。
  3. 要为 MASTER.yaml 文件的演示包集中指定的所有 API 生成 HTML,请输入以下命令(将它输入在一行上):
    php tools/swagger-to-html.php salesconnect.swagger/MASTER.yaml --set demo >c:/swagger/salesconnectAPI.html
  4. 要为模块 OAuth 和 Lead 生成 HTML,请输入以下命令(将它输入在一行上):
    php tools/swagger-to-html.php salesconnect.swagger/MASTER.yaml --modules oauth,leads > c:/swagger/salesconnectAPI.html

结束语

Swagger 是一个为 RESTful API 创建文档的强大工具,而且通过实现自定义扩展、工具和模板,您可以获得对 Swagger 生成的文档的格式和内容的更多选择和控制。通过扩展 Swagger 的功能,您可以包含更多特定于 API 的细节,指定 HTTP 请求和响应,并以 HTML 格式输出文档,以便开发人员和 API 使用者都可以阅读。

下载资源

http://www.ibm.com/developerworks/cn/web/wa-use-swagger-to-document-and-define-restful-apis/index.html

时间: 2024-10-27 00:33:14

使用 Swagger 文档化和定义 RESTful API的相关文章

Swagger文档化restful接口

1.注解 @Api:用在类上,说明该类的作用. @ApiOperation:注解来给API增加方法说明. @ApiImplicitParams : 用在方法上包含一组参数说明. @ApiImplicitParam:用来注解来给方法入参增加说明. @ApiResponses:用于表示一组响应 @ApiResponse:用在@ApiResponses中,一般用于表达一个错误的响应信息 l   code:数字,例如400 l   message:信息,例如"请求参数没填好" l   resp

使用Xcode HeaderDoc和Doxygen文档化你的Objective-C和Swift代码

在一个应用的整个开发过程中涉及到了无数的步骤.其中一些是应用的说明,图片的创作,应用的实现,和实现过后的测试阶段.写代码可能组成了这个过程的绝大部分,因为正是它给了应用生命,但是这样还不够,与它同等重要的还有代码的注释和文档编写.不管代码写的有多好,如果缺少了对应的好的注释文档,很有可能在将来带来麻烦.不幸的是,许多开发者都忽视或忽略了代码文档的重要性,而这非常糟糕,因为好的程序不仅仅是好的代码.它需要更多的东西. 谈到编写注释文档,显然我不是说仅仅简单的在实现文档里添加几行注释.肯定是更多的东

利用未文档化API:RtlAdjustPrivilege 提权实现自动关机

这里主要是利用NTDLL.dll中未文档化的API: RtlAdjustPrivilege 来实现提权.自动关机的功能. RtlAdjustPrivilege定义如下: NTSTATUS RtlAdjustPrivilege ( ULONG Privilege, BOOLEAN Enable, BOOLEAN CurrentThread, PBOOLEAN Enabled ) 参数含义如下:Privilege [In] Privilege index to change.            

Swagger文档转Word 文档

GitHub 地址:https://github.com/JMCuixy/SwaggerToWord/tree/developer 原创作品,转载请注明出处:http://www.cnblogs.com/jmcui/p/8298823.html 一.前言 为什么会产生这个需求呢? 我们公司作为乙方,老是被客户追着要一份API文档,当我们把一个 Swagger 文档地址丢给客户的时候.客户还是很不满意,嫌不够正式!!死活坚持要一份 word 文档 .然后领导给了个接口模板,就把这个活交给我了...

asp.net core web api 生成 swagger 文档

asp.net core web api 生成 swagger 文档 Intro 在前后端分离的开发模式下,文档就显得比较重要,哪个接口要传哪些参数,如果一两个接口还好,口头上直接沟通好就可以了,如果接口多了就有点不适用了,没有接口文档会大大提高前后端的沟通成本.而 asp.net core 可以通过 Swashbuckle.AspNetCore 很方便的集成 swagger 文档,相比之前 nodejs(express) 和 swagger 集成就很麻烦了,大概这就是强类型语言的优势吧.C#

UML是文档化的语言

 The UML Is a Language for Documenting A healthy software organization produces all sorts of artifacts in addition to raw executable code. These artifacts include (but are not limited to) Requirements Architecture Design Source code Project plans T

swagger文档添加jwt认证

最近写的swagger文档,要加jwt授权,所以几经google终于搞定了,简简单单几行配置如下: securityDefinitions: APIKey: type: apiKey name: Authorization in: header security: - APIKey: []

文档化说明的重要性

用通过下面的两个示例,来说明官方给出的文档化说明的重要性.一个是MSDN上给出的说明,一个是GDIView GDI泄漏检测工具官方给出的说明.以这些官方说明为线索,可以找到我们程序出问题的地方,进而将问题解决掉. 1.聊天服务器时间的本地时区和夏时令的问题 (1)TL的聊天时间使用服务器时间,TL底层的XMPP客户端需要和服务器时间进行同步,进而获取服务器时间,用于聊天信息的时间戳.服务器传递过来的是UTC+0的时间,是字符串格式的年月日时间,不是整数时间.XMPP客户端要使用时差bias.mk

Qt的自文档化工具qdoc

在<人月神话>一书中,提及了软件工程中必备的一个概念:自文档化.所谓自文档化,就是把文档和代码合二为一,既增强了文档的可维护性,又增强了代码的可读性,一举两得,何乐而不为呢? 在Qt开发中,就有这样的自文档化工具:qdoc.使用qdoc,通常分三步走. 第一步,添加QDoc注释到必要的.cpp文件或.qdoc文件,在.h文件中添加QDoc注释是无效的. 第二步,编辑.qdocconf配置文件. 第三步,运行qdoc,默认生成HTML文档,命令如下: $xxx/bin/qdoc ./config