open api技术架构 (openapi设计原则)

所有的API端点都与基础URL相关。例如,假设基础URL是https://api.example.com/v1,那么/users端点的路径就是https://api.example.com/v1/users。

https://api.example.com/v1/users?role=admin&status=active
\________________________/\____/ \______________________/
 server URL endpoint query parameters
 path

在OpenAPI 3.0中,你可以使用servers数组为你的API指定一个或多个基础URL。servers取代了OpenAPI 2.0中的host、basePath和schemes关键字。每个服务器都有一个url关键字和一个可选的Markdown格式的description关键字。

servers:
 - url: https://api.example.com/v1 # The "url: " prefix is required

你还可以拥有多个服务器,例如,生产环境和沙盒环境的服务器:

servers:
 - url: https://api.example.com/v1
 description: Production server (uses live data)
 - url: https://sandbox-api.example.com:8443/v1
 description: Sandbox server (uses test data)

服务器URL的格式

服务器的URL格式遵循RFC 3986,通常如下所示:

scheme://host[:port][/path]

其中,host可以是主机的名称或IP地址(IPv4或IPv6)。在OpenAPI 3.0中,出自于OpenAPI 2.0的WebSocket方案(例如:ws://和wss://)也是受支持的。有效的服务器URL,如下所示:

https://api.example.com
https://api.example.com:8443/v1/reports
http://localhost:3025/v1
http://10.0.81.36/v1
ws://api.example.com/v1
wss://api.example.com/v1
/v1/reports
/
//api.example.com

如果服务器URL是相对的,那么便会针对托管给定OpenAPI定义文件的服务器进行解析(详见下文)。注意:服务器URL不得包含查询字符串参数。例如,这是无效的服务器URL:

https://api.example.com/v1?route=

如果没有提供servers数组或者为空,那么服务器URL的默认值为/:

servers:
 - url: /

服务器模板

服务器URL的任意部分 — 方案、主机名或其组成部分、端口、子路径 — 都可以使用变量进行参数化。变量都可以由服务器URL中的{花括号}表示,如下所示:

servers:
 - url: https://{customerId}.saas-app.com:{port}/v2
 variables:
 customerId:
 default: demo
 description: Customer ID assigned by the service provider
 port:
 enum:
 - ’443’
 - ’8443’
 default: ’443’

不像路径参数,服务器变量不使用schema。相反,它们被认为是字符串。变量可以取任意值,也可以限制为枚举值。在任何情况下,都需要一个默认值,如果客户端不提供取值,那么将使用默认值。虽然变量描述是可选的,但是由于它支持用于富文本格式化的Markdown(CommonMark),因此变量描述还是很有用的。服务器模板的常见用例,如下所示:

  • 指定多种协议(例如:HTTP和HTTPS)。
  • SaaS(托管)应用程序,其中每个客户都有自己的子域。
  • 不同地理区域的区域服务器(例如:Amazon Web Service)。
  • SaaS和预置API的单个API定义。

示例

HTTPS和HTTP

servers:
 - url: http://api.example.com
 - url: https://api.example.com

或者使用模板:

servers:
 - url: ’{protocol}://api.example.com’
 variables:
 protocol:
 enum:
 - http
 - https
 default: https

注意:这两个示例在语义上是不同的。第二个示例将HTTPS服务器显式地设为默认服务器,而第一个示例没有默认服务器。

生产环境、开发环境和预发布环境

servers:
 - url: https://{environment}.example.com/v2
 variables:
 environment:
 default: api # Production server
 enum:
 - api # Production server
 - api.dev # Development server
 - api.staging # Staging server

SaaS和预置

servers:
 - url: ’{server}/v1’
 variables:
 server:
 default: https://api.example.com # SaaS server

不同地理区域的区域端点

servers:
 - url: https://{region}.api.cognitive.microsoft.com
 variables:
 region:
 default: westus
 enum:
 - westus
 - eastus2
 - westcentralus
 - westeurope
 - southeastasia

覆盖服务器

可以在路径级别或操作级别上覆盖全局的servers数组。如果某些端点使用和其余的API不同的服务器或基础路径,那么这样做是很方便的。常见的示例,如下所示:

  • 用于文件上传和*载下**操作的不同的基础URL;
  • 已弃用,但功能任然有效的端点。
servers:
 - url: https://api.example.com/v1
paths:
 /files:
 description: File upload and download operations
 servers:
 - url: https://files.example.com
 description: Override base path for all operations with the /files path
 ...
 /ping:
 get:
 servers:
 - url: https://echo.example.com
 description: Override base path for the GET /ping operation

相对URL

servers数组中的URL可以是相对的,例如:/v2。在这种情况下,将针对托管给定OpenAPI定义文件的服务器进行解析。对于托管在客户自己的服务器上的预置安装来说,这种方式非常有用。例如,如果在http://localhost:3001/openapi.yaml中托管的定义指定了url: /v2,那么url会被解析成http://localhost:3001/v2。相对URL的解析规则遵循RFC 3986。此外,API定义中的几乎所有的其他URL(包括OAuth 2流端点、服务条款、外部文档URL,以及其他URL)都可以相对于服务器URL进行指定。

servers:
 - url: https://api.example.com
 - url: https://sandbox-api.example.com
# Relative URL to Terms of Service
info:
 version: 0.0.0
 title: test
 termsOfService: /terms-of-use
# Relative URL to external documentation
externalDocs:
 url: /docs
 description: Find more info here
# Relative URLs to OAuth2 authorization and token URLs
components:
 securitySchemes:
 oauth2:
 type: oauth2
 flows:
 authorizationCode:
 authorizationUrl: /oauth/dialog
 tokenUrl: /oauth/token

注意,如果使用多个服务器,那么相关URL指定的资源应该存在于所有的服务器上。

参考资料

  • 服务器对象
  • URL中的相对引用