OpenAPI Spec 撰寫小記
最近規劃 API 規格打算用 OpenAPI Spec(OAS),但真的不是很熟,所以打算文件刷一遍,這邊做個小記。
OpenAPI Specification v3.1.0 | Introduction, Definitions, & More
OpenAPI Specification (OAS)
什麼是 OpenAPI Specificatio
,簡稱 OAS
- 一個定義 HTTP APIs 簡易規劃介面敘述語言。
- 可以讓
人
與電腦
再不看原始碼情況下和解析網路封包下可以知道 API 怎麼使用 - 當通過OpenAPI正確定義時,消費者可以以最少的實現邏輯來理解並與遠程服務進行交互。類似於接口描述為低級別編程所做的工作,OpenAPI規範刪除了調用服務時的猜測。
價值
- 生產文件工具
- 生產程式
- 生產測試工具
定義
OpenAPI Document
MUST
一個OpenAPI 文件必需
包含
- 至少 paths field
- 至少a components field or a webhooks field
當然必須符合這些規範。
Path Templating
Path Templating 是用大括號{}
的template expressions來展示,URL中的路徑(URL Path)可替換成參數(URL Paramter)
MUST
每個 template expression必需
包含path parameter和 Path Item 或 Path Item’s Operations
path item
為空的話,ACL constraints, matching path parameters為非必要。 ==>這句理解不能,但我猜是指下圖空直。
MUST NOT
path parameters 不能
包含符號。如[RFC3986]: forward slashes (/), question marks (?), or hashes (#).
Media Types
媒體類型定義分佈在幾個資源中。
SHOULD
the media type 定義應該
遵從 [RFC6838]規範.
text/plain; charset=utf-8
application/json
application/vnd.github+json
application/vnd.github.v3+json
application/vnd.github.v3.raw+json
application/vnd.github.v3.text+json
application/vnd.github.v3.html+json
application/vnd.github.v3.full+json
application/vnd.github.v3.diff
application/vnd.github.v3.patch
003-RFC关于媒体类型说明 - bjlhx15 - 博客园
HTTP Status Codes
Hypertext Transfer Protocol (HTTP) Status Code Registry
規範
Version
這邊指 OpenAPI 版本,這邊大至上有看沒懂。感覺就像是大版本小版本之類相容問題,Swagger 版本需要放三碼,
‘3.0.*’ 這個也可以用。但Swagger 工具不能用,我就不深入琢磨。
格式
所有 key 區分大小寫。
兩種 Field
Fixed fields, which have a declared name, and Patterned fields, which declare a regex pattern for the field name.
- 固定欄位
- 花樣欄位
RECOMMENDED
為了讓JSON和YAML格式來回切換,我們推薦
MUST
YAML Tag 必須最低要求符合JSON規則。ref:YAML Ain’t Markup Language (YAML™) Version 1.2
YAML地圖中使用的鍵必須僅限於標量字符串,如YAML Failsafe Schema規則集所定義。YAML Ain’t Markup Language (YAML™) Version 1.2
NOTE: 我們定義 API 使用 OpenAPI 文件可以是 YAML 或 JSON格式。但是 API Request和 Response 的Body不一定是要 JSON 或 YAML。
文件結構
MAY
OpenAPI 文件可以由一個和多個、分段個文件,這部分由編寫者決定。在這種情況下,Reference Object和Schema Object的 $ref
可以被使用。
RECOMMENDED
通常 OpenAPI document 的根文件命名使用 openapi.json
or openapi.yaml
.
資料型態
OAS 的資料型態基於 JSON Schema Specification Draft 2020-12,請注意,整數(Integer)作為類型也得到了支持,並將其定義為沒有分數或指數部分的JSON號。使用Schema Object定義模型,該對像是JSON Schema規範2020-12的超集。
如JSON Schema驗證詞彙所定義的draft-bhutton-json-schema-validation-00,資料類型可以具有可選的修飾符屬性
注意Number
和Integer
差異。Number是含小數點數字。可以看Numeric types — Understanding JSON Schema 2020-12 documentation
Rich Text Formatting
在整個規範中,description
字段被認為是支持Commark Markdown格式的支持。
MUST
如果OpenAPI Tooling呈現豐富的文本,則必須至少支持CommonMark 0.27所述的降級語法。
MAY
工具可以選擇忽略一些共同標記功能來解決安全問題。
Relative References in URIs
MAY
除非另有說明,否則所有 URIs 的屬性都可以是[RFC3986]定義的相對引用。
這邊不知道 URL和 URI是什麼可以看一下URL和URI傻傻分不清,差別到底在哪裡?。
相對引用,包括在reference-object和path-item-object的$ref
欄位。link-object的externalValue
根據[RFC3986],使用引用文檔作為基本URI解決。
如果URI包含片段標識符,則應根據引用文檔的片段分辨率來解析片段。如果引用文檔的表示為JSON或YAML,則根據[RFC6901],應將片段標識符解釋為 JSON-Pointer。
JSON Pointer 不知道可以看Overview of JSON Pointer | Baeldung,感覺跟 JSON Path 有點像。也可以看這篇JSON Pointer。
正如JSON模式規范草案2020-12所述,Schema Objects
中的相對引用,包括任何以$id值出現的引用,使用最近的父$id作為基URI。如果沒有包含$id的父模式,則必須根据[RFC3986]确定基URI。
jsonschema - ‘$id’ property usage in JSON Schema - Stack Overflow
JSON Schema 规范(中文版)
不過我看文件沒有$id
範例,所以這邊就不先深入探討。
Relative References in URLs
除非另有說明,否則所有屬性URL的屬性可能是[RFC3986]定義的相對引用。除非另有說明,否則使用Service Object 中定義為基本 URL解決相對引用。請注意,這些本身可能與引用文檔有關。
Schema
在下面的描述中,如果一個字段沒有顯式的REQUIRED或用MUST或SHALL描述,它可以被認為是OPTIONAL。
以下真的太多內容了,所以我覺得不重要的就不會記到這邊。
OpenAPI Object
REQUIRED
- openapi(string) OAS 版本
- info(Info Object) 資訊
- paths([Paths Object]) The available paths and operations for the API.
OPTIONAL
- components([Components Object]) 可寫定義元件
- security([Security Requirement Object]) API 安全用
- tags([Tag Object]) 分類用
- externalDocs(External Documentation Object) 額外文件
- servers([Server Object]) Sever 資訊
webhooks 3.1.0才有的東西,目前不知道有什麼特別作用。
Info Object
該對象提供有關API的元數據。如果需要,客戶可以使用元數據,並可以在編輯或文檔生成工具中呈現。
REQUIRED
- title(string)
- version(string)
OPTIONAL
- summary(string)
- description(string)
- contact(Contact Object)
- license(License Object)
Server Object
REQUIRED
- url(string) 可以用誇號字段
{brackets}
搭配variables
field來搭配變數使用。
OPTIONAL
- description
- variables(Map[string, Server Variable Object]) 可以搭配 url 變數使用
This object MAY be extended with Specification Extensions.
可以使用Specification Extensions作擴展
範例
|
|
|
|
Server Variable Object
REQUIRED
- default(string) If the enum is defined, the value MUST exist in the enum’s values
OPTIONAL
- enum
- description
Components Object
- schemas (Map[string, Schema Object])
- responses (Map[string, Response Object | Reference Object])
- parameters (Map[string, Parameter Object | Reference Object])
- examples (Map[string, Example Object | Reference Object])
- requestBodies (Map[string, Request Body Object | Reference Object])
- headers (Map[string, Header Object | Reference Object])
- securitySchemes (Map[string, Security Scheme Object | Reference Object])
- links (Map[string, Link Object | Reference Object])
- callbacks (Map[string, Callback Object | Reference Object])
- pathItems (Map[string, Path Item Object | Reference Object])
This object MAY be extended with Specification Extensions.
All the fixed fields declared above are objects that MUST use keys that match the regular expression: ^[a-zA-Z0-9.-_]+$.
Paths Object
- /{path} (Path Item Object)
必須要/
開頭。規則上面Path Templating
有提到
This object MAY be extended with Specification Extensions.
Path Item Object
- $ref (string)
- summary (string)
- description (string)
- get (Operation Object)
- put (Operation Object)
- post (Operation Object)
- delete (Operation Object)
- options (Operation Object)
- head (Operation Object)
- patch (Operation Object)
- trace (Operation Object)
- servers ([Server Object])
- parameters ([Parameter Object | Reference Object])
這邊文件有特別說明 Paramters
- 這些參數可以在操作級別上覆蓋,但不能在此處刪除。
- 該列表不得包含重複的參數。 MUST NOT
- 唯一參數由
name
和location
的組合定義。
這邊名稱是指這個(name)、location是指這個(in) - 該列表可以使用參考對象鏈接到 OpenAPI Object’s components/parameters的參數。
Operation Object
Operation Object
這邊比較意外沒有必填寫項目。
我把我覺得重要的簡單寫一下。先前寫過事項就不再寫了
- operationId (string)
用于標識操作的惟一字符串。id在API中描述的所有操作中必須是唯一的。operationId區分大小寫。工具和庫可以使用operationId來唯一標識一個操作,因此,建議遵循通用的編程命名約定。 - tags
- summary
- description
- requestBody(Request Body Object | Reference Object)
在其他情況下,HTTP規格模糊(例如GET,HEAD和DELETE),請求機體被允許但沒有明確定義的語義,應避免使用。 ==>這邊我是認為 POST時候可能就會用到這個 - responses (Responses Object)
從執行此操作返回的可能responses的列表。 - deprecated (boolean)
聲明此操作要棄用。消費者應避免使用聲明的操作。默認值為false。 - security ([Security Requirement Object])
- servers ([Server Object])
Parameter Object
這邊注意用的參數有四種類型,請看下面。
Parameter Locations
There are four possible parameter locations specified by the in
field:
- path - Used together with Path Templating, where the parameter value is actually part of the operation’s URL. This does not include the host or base path of the API. For example, in /items/{itemId}, the path parameter is itemId.
- query - Parameters that are appended to the URL. For example, in /items?id=###, the query parameter is id.
- header - Custom headers that are expected as part of the request. Note that [RFC7230] states header names are case insensitive.
- cookie - Used to pass a specific cookie value to the API.
看似應該沒有BODY內容,這邊需要注意一下。
Fixed Fields
REQUIRED
- name (string)
區分大小寫 - in (string) 只有四種"query", “header”, “path” or “cookie”
OPTIONAL
- description
- required paramter location(in) 選擇 path 就必須預設值為
true
。但是其他的話預設為false
。 - deprecated
- allowEmptyValue
這邊特別紀錄
Style
一般我們知道很多後端傳送值都有自己的樣式,這邊可以特別調整。這邊我就不詳細記錄
範例
|
|
Request Body Object
REQUIRED
- content (Map[string, Media Type Object]) e.g. text/plain overrides text/*
OPTIONAL
- description (string)
- required (boolean) Defaults to false.
範例
|
|
Media Type Object
- schema (Schema Object)
- example (Any)
example object 應為Media Type Objec指定的正確格式
if referencing a schema which contains an example, the examples value SHALL override the example provided by the schema.(example object會把 $ref覆蓋掉)
examples字段與example字段互斥(看似應該擇一填寫?) - examples (Map[ string, Example Object | Reference Object])
- encoding (Map[string, Encoding Object])
Considerations for File Uploads
上傳檔案
|
|
|
|
推薦用
|
|
Support for x-www-form-urlencoded Request Bodies (POST常用)
|
|
Responses Object
OpenAPI Specification v3.1.0 | Introduction, Definitions, & More
Fixed Fields
- default (Response Object | Reference Object)
Patterned Fields
- HTTP Status Code (Response Object | Reference Object)
範例
|
|
Response Object
This object MAY be extended with Specification Extensions.
Fixed Fields
REQUIRED
- description (string) 第一次看到敘述必填。
OPTIONAL
- headers (Map[string, Header Object | Reference Object]) 這邊不能設定"Content-Type" header
- content (Map[string, Media Type Object])
- links (Map[string, Link Object | Reference Object])
範例
|
|
純文字
|
|
with header
|
|
沒會應東西
|
|
Example Object
- summary (string)
- description (string)
- value (Any)
- externalValue (string) The value field and externalValue field則一填寫
範例
In a request body:
|
|
In a parameter:
|
|
In a response:
|
|
Link Object
先不深入研究,好像也很重要。
OpenAPI Specification v3.1.0 | Introduction, Definitions, & More
Header Object
OpenAPI Specification v3.1.0 | Introduction, Definitions, & More
跟 Paramter Object 一樣,但不能寫in
和name
。
第一次看這個會覺得怎麼不能寫name
很奇怪,但上層是Map[string,Header Object]
所以就這麼單純。
範例
|
|
Tag Object
Fixed Fields
REQUIRED
name
OPTIONAL
description
|
|
Reference Object
REQUIRED
- $ref (string) URI
OPTIONAL
- summary (string)
- description (string)
範例
|
|
Schema Object
我覺得這邊很玄學。就先跳過這章節,我覺得看範例可以很快知道要怎麼用。
好像規格定義在裡面https://spec.openapis.org/oas/3.1/dialect/base
雖然我跳過,但這個我還是覺得很重要。
Discriminator Object
看起來是分辨物件用。
The discriminator object is legal only when using one of the composite keywords oneOf, anyOf, allOf.
Discriminator Object 僅在使用一個複合關鍵字之一 oneOf, anyOf, allOf時才是合法的。
Fixed Field
REQUIRED
- propertyName (string) 定義 type 範例
OPTIONAL
- mapping (Map[string, string]) 定義 type 名稱指定schema
這邊推薦看 line-bot-sdk-java/DemographicFilter.java at cbcb096023f2de84684751839656a0c458f6ee41 · line/line-bot-sdk-java 他們實作才看得懂這邊在做什麼?
|
|
這部分支援還要看有沒有找到相關方法去解決這段處理。
範例
|
|
Security Scheme Object
- type => “apiKey”, “http”, “mutualTLS”, “oauth2”, “openIdConnect”.
我覺得這章節看範例比較快。
範例
OpenAPI Specification v3.1.0 | Introduction, Definitions, & More
彩蛋
如何利用 OpenAPI 及 WebHooks 讓老舊的網路服務也可程式化