使用Swagger和OpenAPI设计API

Swagger和OpenAPI介绍

什么是OpenAPI

OpenAPI规范(OAS)是对基于HTTP的API的描述,通常是RESTful API,目的是为定义一种标准的、与语言无关的接口。它允许人类和计算机在不访问源代码、文档或通过网络流量检查的情况下发现和理解服务的功能。如果定义正确,使用者可以用最少的实现逻辑理解远程服务并与之交互。

它以YAML、JSON文件或定义的形式出现,描述API的输入和输出。它还可以包括API托管在哪里,访问它需要什么授权,以及消费者和生产者(如WEB开发人员)需要的其他细节等信息。

定义可以手工编写,可以通过API工具(swagger-editor)编写,也可以通过代码生成。文档生成工具可以使用OpenAPI定义来显示API,代码生成工具可以生成各种编程语言的服务器和客户端、测试工具和许多其他用例。

OpenAPI定义示例

openapi: 3.0.0
info:
  title: Dog API
  version: 1.0.0
servers:
- url: https://dog.ceo/api
paths:
  /breed/{breedName}/images:
    get:
      description: Get images of dog breeds
      parameters:
      - in: path
        name: breedName
        schema:
          type: string
          example: hound
        required: true
      responses:
        '200':
          description: A list of dog images
          content:
            application/json:
              schema:
                type: object
                properties:
                  status:
                    type: string
                    example: success
                  message:
                    type: array
                    items:
                      type: string
                      example: https://images.dog.ceo/breeds/hound-afghan/n02088094_1003.jpg

从上面的简单示例中,我们可以收集一些关于它所描述的单个操作以及如何使用它的片段。

  • API托管在dog.ceo/api
  • 有一个GET操作:GET /breed/{breedName}/images
  • URI中的breedName是字符串变量
  • 成功的响应(200)将给我们一个JSON数组,其中每个条目都是一个包含messagestatus字段的对象
  • message字段是一个字符串数组,这些字符串是狗图片的URL

这是很有用的信息。开发人员可以构建客户端来使用API,产品经理可以确定API是否适合他们的需求和符合他们的标准,文档团队可以使用它作为显示人类可读文档的基础。

作为使用OpenAPI定义的一个例子,我们可以将这个定义加载到一个名为SwaggerUI的工具中(后面详细介绍)。它将基于定义呈现文档,并提供其他小细节。它看起来就像下面这样:

ch01-swagger-ui-dogs-api-get-breed-images

OpenAPI定义的应用场景

一旦我们有了API定义,我们就会使用工具来利用它们,构建更大的抽象和更自动化的工作流。

下面的图表显示了OpenAPI定义如何适应组织的工作流程:

mental-model-swagger

该图显示了如何利用OpenAPI定义,这些定义由工具或从代码中提取注释来描述。然后将它们转换为API文档、服务器Stubs/Mocks和客户端SDK。当然还有更多的工作流程可以绘制出来,这些工作流程可以根据业务用例提供更具体的价值。

例如:

  • 自动化测试部分(API)
  • 获得API设计的早期反馈
  • 确保API一致性
  • 比较不同版本的API变化等等

什么是Swagger

一开始有SwaggerUI和一个关于编写描述HTTP API的YAML文件的粗略指南。后来,更多的工具建立在这个指南的基础上,并很快成为规范和标准。这些工具和这个规范被统称为“Swagger”。该规范变得更加成熟,并以开源的形式发布,鼓励社区创建更多的工具。他们很快就开始在规范中加入特性,这些特性最终开始被大公司采用。

然后在2015年SmartBear采用了它,并将规范部分捐赠给了Linux基金会。在演进过程中,规范部分随后被重命名为OpenAPI规范,SmartBear保留术语Swagger的版权。

SmartBear公司广为人知的产品:SoapUI、Swagger CodeGen、Swagger Editor、Swagger UI、Cucumber等

RESTful API & HATEOAS

HATEOAS(Hypermedia as the Engine of Application State)是REST应用架构的一个约束,它使REST风格的架构有别于大多数其他网络应用架构。术语“Hypermedia”(超媒体)指的是任何包含链接到其他形式的媒体,如图像、电影和文本的内容。

REST架构风格允许我们在响应内容中使用超媒体链接。它允许客户端通过遍历超媒体链接动态导航到适当的资源。

在概念上,浏览超媒体链接与网络用户通过点击相关的超链接来浏览网页以达到最终目的是一样的。

例如,下面给出的JSON响应可能来自像HTTP GET http://api.domain.com/management/departments/10这样的API

{
    "departmentId": 10,
    "departmentName": "Administration",
    "locationId": 1700,
    "managerId": 200,
    "links": [
        {
            "href": "10/employees",
            "rel": "employees",
            "type" : "GET"
        }
    ]
}

在上例中,服务器返回的响应包含指向员工资源10/employees的超媒体链接,客户端可以遍历这些超媒体链接来读取属于该部门的员工。

上述方法的优点是,从服务器返回的超媒体链接驱动应用程序的状态,而不是反过来。

在现实世界中,当你访问一个网站时,你会点击它的主页。它提供了一些快照和链接到网站的其他部分。你点击它们,然后你就会得到更多的信息以及更多与上下文相关的链接。

与人与网站的交互类似,REST客户机访问初始API URI并使用服务器提供的链接来动态发现可用的操作并访问所需的资源。客户端不需要预先了解服务或工作流中涉及的不同步骤。此外,客户端不再需要为各种资源硬编码URI结构。HATEOAS允许服务器在API演进时更改URI,而不会破坏客户端。

Spring HATEOAS:https://spring.io/projects/spring-hateoas

OpenAPI的作用

OpenAPI描述了基于HTTP的API(包括RESTful API),所以当您的任务是设计、管理以及在某些情况下使用API时,那么OpenAPI是有意义的。当然,如果您正在处理其他不利用HTTP的API技术,如gRPC或GraphQL,那么OpenAPI就毫无意义了。

API-First

API优先方法意味着对于任何给定的开发项目,API都被视为“一等公民”。关于项目的一切都围绕着这样一个理念:最终产品将被外部设备使用,而API将被客户端应用程序使用。API优先的方法包括开发一致和可重用的API,这可以通过使用API描述语言来建立API应该遵循什么样的契约来实现。建立契约需要花更多的时间考虑API的设计。在编写任何代码之前,它还经常涉及到额外的规划和与协作,以提供有关API设计的反馈。

API优先方法的好处

  • 开发团队可以并行工作
  • 降低开发应用程序的成本
  • 提高发布速度
  • 确保良好的开发者体验
  • 降低失败的风险

API消费者

对于API消息者,如果需要使用某些API,可能需要一个SDK,使用OpenAPI,可以为许多不同的语言生成SDK。定制SDK以满足一些特性的需求。然后,OpenAPI描述的每一个API都可以转换成API消息者所选择语言的SDK。通常由SwaggerCodegen或OpenapiGenerator等工具生成SDK,然后在此基础上进一步开发。

根据OpenAPI定义生成的Mock服务进行开发。

API创建者

同样的,可以使用OpenAPI结合工具生成模板代码,从OpenAPI定义生成模板代码和Subs可以提高速度和一致性。

API设计者

OpenAPI是与消费者和生产者沟通的媒介,允许设计者在过程早期获得反馈,并根据反馈进行迭代。

当涉及到管理多个API时,一致性也起着重要作用。将所有API标准化以拥有一致的模式就成为可能。OpenAPI定义就是这样一种度量。

OpenAPI规范简介

OpenAPI规范是描述RESTful或基于HTTP的API的方式,相当于模板。使用一组规则和约束来展示所描述API。

mental-model-swagger-api-definitions

如果遵循模板,那么软件(和人员)将能够使用一些可用的工具来处理API描述。不仅能够理解所描述的内容,而且还能够将其作为系统的一部分使用,这比使用定制的规范描述要省力得多。

Field Name Type Description
openapi string 必须,该字符串必须是OpenAPI文档使用的OpenAPI规范版本的语义版本号。工具规范和客户端应该使用openapi字段来解释OpenAPI文档。这与API信息无关。
info Info Object 必须,提供有关API的元数据。根据需要,工具可以使用元数据。
servers Server Object 服务器对象数组,提供到目标服务器的连接信息。如果没有提供servers属性,或者是一个空数组,默认值将是url值为/的Server Object。
paths Paths Object 必须,API的可用路径和操作。
components Components Object 可复用的一些配置对象,例如,请求参数对象描述、响应结果对象的描述
security Security Requirement Object 可以跨API使用哪些安全机制的声明。值列表包括可使用的替代安全性需求对象。仅需要满足其中一个安全需求对象就可以授权请求。单个操作可以覆盖此定义。要使安全性成为可选的,可以在数组中包含一个空的安全性需求({})。
tags Tag Object 使用附加元数据的规范所使用的标记列表。解析工具可以使用标记的顺序来反映它们的顺序。并非操作对象使用的所有标记都必须声明。未声明的标记可以随机组织或基于工具的逻辑。列表中的每个标记名必须是唯一的。
externalDocs External Documentation Object 额外的外部文档。

ch03-example-openapi-fragment-annotated

SwaggerEditor

ch04-overview-editor-highlighted

SwaggerEditor是一个用于编写OpenAPI定义的工具。它是一个Web应用程序,在线托管在editor.swagger.io上,也可以本地部署,像许多Swagger工具一样,它是开源的。这个Web应用程序包含一个文本编辑器和一个显示生成文档的面板。文档窗格将显示我们输入的结果,给我们即时的反馈,并对我们输入的内容进行校验。

ch04-swagger-editor-initial-page

ch04-swagger-editor-farmstall-v1-get-reviews

  • Editor Panel
  • Toolbar:导入导出、格式转换、版本转换、快捷插入、服务端和客户端代码生成器
  • UI Docs Panel

Open API v3 VS Swagger v2

Swagger是API开发人员设计、构建、开发和使用RESTful API的最大且广泛使用的开源框架之一。Swagger规范便于创建API的RESTful契约,包括所有可读格式的资源定义、可用端点、操作参数、认证机制、契约信息和许可等。随Swagger规范而来的工具,如Swagger-Editor(用于创建、编辑、验证和测试OpenAPI/Swagger定义的基于Web的编辑器),Swagger-UI(用于可视化和测试OpenAPI/Swagger定义的基于Web的界面),将使API开发人员的世界中生活得更轻松。

在过去的几年中,API开发人员一直在使用Swagger 2.0规范来定义API。后来,它被捐赠给了Linux基金会,并被命名为Open API规范,一个新的规范发布了,其中包含了大量的新特性和改进,称为Open API 3.0。与Swagger 2.0相比,Open API规范采用了更模块化和可重用的方法来定义API,在描述请求响应模型和底层安全信息时,它更强大。

  • 提高可重用性
  • 参数的变化
  • 示例描述改进
  • 内容协商支持
  • 支持描述回调
  • 能够表示操作之间关系的链接

让我们仔细看看Open API中有哪些新功能,有哪些结构上的改进,以及如何从Swagger 2.0迁移到Open API 3.0。

Metadata Changes

所有对swagger的引用都已更改为openapi。因此swagger 2.0的定义版本必须做如下更改。

"swagger": "2.0" --> "openapi": "3.0.0"

Structural Changes

swagger_2.0_and_Open_API_3.0

Server Definition

openapi: 3.0.0
info: 
  version: '1.0.0'
  title: 'My Service APIs'
  description: 'API to demonstrate OAS3.0'
servers:
  - url: https://dev.myapp.com/api
    description: My Dev Server
  - url: https://beta.myapp.com/api
    description: My Beta Server
  - url: https://live.myapp.com/api
    description: My Live Server
paths: {}

可重用组件(Reusable Components)

所有参数、响应和定义都在通用组件对象下进行描述。definitions对象现在重命名为schemas。同样的schema对象可以在响应和请求主体中使用。

openapi: 3.0.0
info: 
  version: '1.0.0'
  title: 'My Service APIs'
  description: 'API to demonstrate OAS3.0'
paths: {}
components: 
   schemas: 
      Employee: 
        properties: {}

Parameter Changes

Swagger 2.0支持两种类型的参数:查询参数和基于路径的参数。它们被移到了OAS3.0。此外,OAS3.0支持这些更改。

New Headers Params

parameters:
  - name: api_key
    in: header
    schema:
      type: string

New Cookies Params

parameters: 
  - name: limit
    in: cookie
    schema: 
      type: integer
      minimum: 10
      maximum: 100
      example: 20

New requestBody Option

paths: 
  /employees: 
    post: 
      requestBody: 
         required: true
         content: 
            application/json: 
               schema: {}
            application/xml: 
               schema: {}

Use of schema object for param

现在,定义任何参数都需要在每个可能的用例中使用schema对象。

paths: 
  /employees: 
    get: 
      parameters: 
         - name: limit
           in: query
           schema: 
              type: integer
              minimum: 10
              maximum: 100
              example: 20

Content Negotiation Support

Consumes and Produces removed

现在可以根据请求和响应体媒体类型在单独的路径级别上定义。

Different Media Types

可以分别在请求和响应体中定义。使API支持一个端点的一种响应类型和另一个端点的其他响应类型。

paths: 
  /employees: 
    get: 
      parameters: {}
      responses: 
         200:
           content: 
              application/json: 
                schema: {}                              
              application/xml:
                schema: {}

Better File Upload Support

现在支持上传文件数组。

Ranges in Responses

可以定义范围代码,而不是定义单个响应。可以为200的所有范围定义一个响应,为400的所有范围定义其他响应。支持的范围为:1XX、2XX、3XX、4XX和5XX。

支持描述回调

这是OAS3.0中的全新特性。如果想定义一个API端点,它会在请求完成时调用URL,现在就可以定义了。

表示操作之间关系的链接

HTTP Links是获取资源相关链接的现代方式。Github多年来一直在其API中使用它。

paths:
  /users/{id}:
    parameters:
    - name: id
      in: path
      required: true
      description: the user identifier, as userId 
      schema:
        type: string
    get:
      responses:
        '200':
          description: the user being returned
          content:
            application/json:
              schema:
                type: object
                properties:
                  uuid: # the unique user id
                    type: string
                    format: uuid
       links:
          address:
            # the target link operationId
            operationId: getUserAddress
            parameters:
              # get the `id` field from the request path parameter named `id`
              userId: $response.body.uuid

RAML

RAML介绍

RAML规范描述了RESTful API建模语言(RAML:RESTful API Modeling Language)。RAML是一种人和机器可读的语言,用于定义RESTful应用程序编程接口(HTTP API)。RAML旨在通过提供一种API提供者和API使用者可以用作相互契约的格式来改进API的规范。例如,RAML可以方便地为客户机和服务器实现提供用户文档和源代码存根。这样的规定简化和增强了使用RESTful API的可互操作应用程序的定义和开发。

RAML引入了资源类型和特征的创新概念,用于描述和重用资源和相关方法的模式。使用资源类型和特征可以减少RESTful API设计中的重复,并促进API内部和跨API的一致性。

参考文档

1 个赞

如何编写基于OpenAPI规范的API文档.pdf (1.1 MB)