OpenAPI介紹-初步認(rèn)識(shí)

介紹:

OAS就是定義基于http的遠(yuǎn)程api的文檔的一種規(guī)范

什么是API? API就是應(yīng)用程序接口接口,比如說像編程中調(diào)用到的方法/函數(shù),就是api之一,這個(gè)時(shí)候api是由方法的名稱、參數(shù)、返回值等組成的。對(duì)于本地api來說,交互雙方(調(diào)用者和提供api者)是處于同一臺(tái)機(jī)器的,比如你自己機(jī)器的標(biāo)準(zhǔn)c庫是由c編譯器程序提供的。

而OAS就是聚焦于遠(yuǎn)程API的描述的,一般來說,提供API服務(wù)的一方稱為提供方,而調(diào)用API的一方稱為消費(fèi)者。

OAS的優(yōu)點(diǎn):

  • 文檔校驗(yàn)和檢查;

  • 數(shù)據(jù)校驗(yàn);

  • 文檔生成;

  • 代碼自動(dòng)生成;

  • mock服務(wù);

  • 安全分析;

  • 同時(shí)可供機(jī)器和人類閱讀;

  • 強(qiáng)大而完善的工具體系

    使用 API 是計(jì)算機(jī)科學(xué)中的日常實(shí)踐,因?yàn)樗鼈兊暮锰幨俏阌怪靡傻摹?舉個(gè)最突出的例子:
    API 提供信息隱藏:API 的任何一方(提供者和消費(fèi)者)都不知道另一方的實(shí)現(xiàn)細(xì)節(jié)。 只要兩者都遵守 API,就可以根據(jù)需要隨意更改,而對(duì)方甚至不會(huì)注意到。
    API 也稱為契約,因?yàn)樗鼈儽徽J(rèn)為是牢不可破的:提供者承諾不會(huì)改變其 API 并在未來幾年繼續(xù)兌現(xiàn)它。 有了這個(gè)承諾,消費(fèi)者就可以開始開發(fā)他們的部件并充滿信心地依賴 API 提供的功能。
    現(xiàn)在,為了讓所有相關(guān)方遵守相同的 API,必須對(duì)其進(jìn)行精確定義。 下一節(jié)將介紹傳統(tǒng)上如何實(shí)現(xiàn)這一目標(biāo)。
    一般來說,API都會(huì)配套有參考指南,用于解釋如何來使用該api。而不幸地是,每個(gè)軟件開發(fā)者或許都會(huì)面臨以下的幾種情況:

  • 不熟悉文檔

  • 文檔不全

  • 過時(shí)的信息

  • 讀者無法理解的語言
    為了解決這些問題,程序開發(fā)者往往需要大量時(shí)間來閱讀源碼、調(diào)試程序或者分析網(wǎng)絡(luò)流量,這太浪費(fèi)時(shí)間了
    更現(xiàn)實(shí)的情況是,很多使用中會(huì)出現(xiàn)的問題,在你真真使用之前都難以發(fā)現(xiàn)
    api描述文件(也稱為契約)是一種機(jī)器可讀的api規(guī)范(需要配合一些支持oas的工具,比如swagger)。它應(yīng)該是盡可能完整且詳細(xì)的(就是你幾乎盡可能地把這個(gè)api涉及到細(xì)節(jié)都給描述出來了,從url到請(qǐng)求參數(shù)、響應(yīng)參數(shù)、content-type、cookie、其他用到的header、以及包括對(duì)這些內(nèi)容的描述、字段類型啥的全都給說清楚),雖然這不是強(qiáng)制(如果把一切都寫清楚也不太現(xiàn)實(shí))。這就是合同/契約 一樣,你要是描述的越?jīng)]有歧義,那它就越有用。
    跟一般的人類可讀的文檔相比(也就是以往開發(fā)人員自行手寫的比如markdown或者其他形式的文檔),它最大的優(yōu)勢(shì)就是可以由機(jī)器自動(dòng)處理,為本指南開頭列出的好處敞開了大門。
    只要是按照OAS編寫的api描述,就可以很簡單利用工具生成面向人類可讀的文檔;更進(jìn)一步地說,它還能利用api描述直接生成即時(shí)可用的目標(biāo)代碼,這樣生成的客戶端代碼是完全匹配api描述的,也避免了我們手動(dòng)編寫代碼集成的時(shí)候一些錯(cuò)誤。

OAS解釋:

我們?cè)俅蝸斫榻B下OAS,OpenAPI規(guī)范(OAS)是一種與供應(yīng)商無關(guān)的基于http的遠(yuǎn)程api描述格式。它最初基于2015年SmartBear Software捐贈(zèng)的Swagger 2.0規(guī)范。
總而言之,它就是用于定義和描述基于http或者基于類似http的遠(yuǎn)程api的一種規(guī)范。

OAS規(guī)范:

整個(gè)OPENAPI的規(guī)范是很長的,對(duì)于新手來說是令人生畏的
所以我們需要先按主題、組織,簡化瀏覽

OpenAPI文檔結(jié)構(gòu):

OpenAPI文檔是一個(gè)文本文件,一般是xxx.json或者xxx.yaml,是以json或者yaml格式來書寫的
該文件被稱為根文檔并且可以被分割為多個(gè)json或者yaml文件 以讓其更加清晰
一般來說,JSON不支持注釋,需要:用逗號(hào)分隔字段,對(duì)象周圍用花括號(hào)括起來,字符串周圍用雙引號(hào)括 起來,數(shù)組周圍用方括號(hào)括起來。另一方面,YAML在數(shù)組項(xiàng)之前需要連字符,并且嚴(yán)重依賴縮進(jìn),這在大文件中可能很麻煩(在JSON中縮進(jìn)完全是可選的)。YAML通常是首選的,因?yàn)樗晕p小了文件大小,但是這兩種格式是完全可以互換的(只要使用YAML 1.2)。這些頁面中的所有示例都將在YAML中給出。
然而,YAML是JSON的超集,這意味著這兩種語法可以混合使用。雖然一般情況下不推薦這樣做,但有時(shí)還是會(huì)派上用場(chǎng)的。例如
![p-images.jianshu.io/upload_images/26589460-1a456adb365a5a23.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

最小化的文檔結(jié)構(gòu):

完全準(zhǔn)確地說,OpenAPI文檔就是一個(gè)完全符合OAS的單個(gè)JSON對(duì)象
這里有個(gè)站點(diǎn)可以以樹形圖的形式展示一個(gè)符合OAS的結(jié)構(gòu),可以用來幫助熟悉OAS規(guī)范
https://openapi-map.apihandyman.io/

image.png

最小結(jié)構(gòu)中info 和openapi字段是必須的,此外paths,components,webhooks這3個(gè)字段中也必須有至少的其中一個(gè)存在
image.png

接著簡單介紹下3個(gè)字段,openapi,info,paths
  • openapi:這個(gè)用來指示當(dāng)前api文檔所采用的OAS的版本

  • info:這個(gè)用來指示當(dāng)前api的版本以及當(dāng)前api的其他信息,注意這里指的當(dāng)前我們自己寫的api的信息,要注意它和openapi這個(gè)規(guī)范的版本有所不同


    image.png
  • paths,這個(gè)用于指示當(dāng)前api的所有端點(diǎn),包括他們的參數(shù)以及所有可能的服務(wù)器響應(yīng)。在自動(dòng)生成服務(wù)器和客戶端代碼的時(shí)候主要就是依據(jù)這里的描述了,按照這個(gè)思路,我們可以寫一個(gè)最小結(jié)構(gòu)的符合OAS的文檔出來

openapi: 3.1.0 
  info: 
    title: test 
    version: 0.0.1 
  paths: {} 

OpenAPI端點(diǎn)endpoints
api端點(diǎn)在OAS中就是上面剛剛提到的paths對(duì)象


image.png

paths:需要注意的是paths字段的值是個(gè)對(duì)象,而不是一個(gè)數(shù)組,其中每個(gè)字段的鍵是端點(diǎn)名字,值是一個(gè) 路徑項(xiàng)對(duì)象,就像這樣:

paths: {
  "/users": {路徑項(xiàng)對(duì)象}, 
  "/posts": {路徑項(xiàng)對(duì)象} 
}

路徑都必須以 / 開頭,為什么paths對(duì)象要采用對(duì)象而不是數(shù)組,是因?yàn)檫@樣可以更加明顯地表示paths對(duì)象中的端點(diǎn)名稱是唯一的

            path item object:路徑項(xiàng)對(duì)象也是一個(gè)對(duì)象,其中的字段名是允許的http操作方法(get post put delete ...),值是一個(gè)操作對(duì)象(operation object), 需要注意的是在路徑項(xiàng)對(duì)象上還可以指定所有操作都接收的公共屬性,比如summary,description,比如
paths: {
    "/users": {
        "get": {操作對(duì)象},
        "summary": "這是所有操作公共的摘要信息,當(dāng)然要是個(gè)別操作有不同的話,也可以單獨(dú)在該操作對(duì)象中指定" 
    },
    "/posts": {路徑項(xiàng)對(duì)象}
}

operation object操作對(duì)象,除了summary和description以外,操作對(duì)象一般來說還會(huì)描述操作的參數(shù)、載荷、可能的服務(wù)器響應(yīng)等 paths:

/board:

get:

  summary: Get the whole board

  description: Retrieves the current state of the board and the winner.

  parameters:

    ...

  responses:

    ...

            responses object響應(yīng)對(duì)象集合,注意這里還是responses,帶了個(gè)s,這個(gè)字段在操作對(duì)象中

            用描述該操作有可能的各種服務(wù)器會(huì)給出的回答。這個(gè)對(duì)象中,每個(gè)字段的名字都是一個(gè)用引號(hào)括起來的http狀態(tài)碼,而它對(duì)應(yīng)的值就是一個(gè)響應(yīng)對(duì)象response object(注意這里沒有帶s了),進(jìn)而描述每個(gè)響應(yīng)對(duì)象的細(xì)節(jié),注意,在responses object中至少要指定一個(gè)狀態(tài)碼,并且最好是一個(gè)表示成功的狀態(tài)碼,比如200.

response object響應(yīng)對(duì)象,這里就是描述一個(gè)操作對(duì)象中具體的狀態(tài)碼對(duì)應(yīng)的返回信息了,

這個(gè)對(duì)象中必須要有一個(gè)description,用于對(duì)該響應(yīng)對(duì)象以及該狀態(tài)碼進(jìn)行補(bǔ)充描述(本質(zhì)上應(yīng)該就是通用http狀態(tài)碼描述)

body of message:

上一步最后展示的是api端點(diǎn)中的響應(yīng)對(duì)象,它位于操作對(duì)象中,實(shí)際上,在操作對(duì)象中除了description和responses以外,當(dāng)然還有很多其他字段,比如還有request body object,跟響應(yīng)對(duì)象相對(duì)應(yīng),它是請(qǐng)求對(duì)象。這里來介紹下在請(qǐng)求和響應(yīng)對(duì)象中都會(huì)用到的一個(gè)字段: content,內(nèi)容對(duì)象

image.png

content字段:它是標(biāo)準(zhǔn)媒體類型和OpenAPI媒體對(duì)象(OpenAPI Media Type Object)之間的映射對(duì),比如:

responses: {

"200": {

    content: {

        "application/json": {OpenAPI媒體對(duì)象},

"test/html": {OpenAPI媒體對(duì)象}

    }

}

}

這意味著,可以根據(jù)不同的格式來返回內(nèi)容

Media Type Object媒體類型對(duì)象: 媒體類型對(duì)象就是一個(gè)媒體類型對(duì)應(yīng)著的具體的內(nèi)容結(jié)構(gòu),比如:

content:
application/json:
schema:
...

schema object模式對(duì)象: 模式對(duì)象用于定義數(shù)據(jù)類型,其可以是原子類型(整數(shù),字符串),數(shù)組或者對(duì)象,取決于其中的type字段,注意,當(dāng)schema的content位于responses就是定義的響應(yīng)數(shù)據(jù),當(dāng)位于request body object中,就是定義的請(qǐng)求數(shù)據(jù)

注意,對(duì)于我們平時(shí)開發(fā)的json 格式的api來說的,一般content中的schema肯定都是object,因?yàn)槲覀兌际欠祷匾粋€(gè)對(duì)象,比如


image.png

這就是我們平時(shí)接口返回的一個(gè)典型例子,對(duì)于這種情況,我們應(yīng)該將schema設(shè)置為object,然后再在object中進(jìn)一步定義其下的各個(gè)字段

這里介紹各個(gè)數(shù)據(jù)類型的定義要求:

在schema對(duì)象中,通過type字段定義數(shù)據(jù)類型,type是一個(gè)字符串,可用的值為:number,string,boolean,array,object,根據(jù)type字段的值,會(huì)有一些配套的其他字段用于擴(kuò)充定義

比如:對(duì)于string類型,就可以附加minLength和maxLength用于指定字符長度

對(duì)于integer類型,minimum和maximum字段可以用于指定最大最小值。

無論什么類型的值,都可以通過enum字段來限制該字段的值必須在它規(guī)定的范圍內(nèi),enum是數(shù)組

對(duì)于數(shù)組類型,必須指定items字段,它也是一個(gè)schema對(duì)象,通過它來定義數(shù)組中的每個(gè)元素的類型。除此之外,數(shù)組的長度可以通過minItems和maxItems字段來指定

最后,對(duì)于對(duì)象類型的字段,必須通過properties字段來指定對(duì)象中的屬性,properties是一個(gè)對(duì)象,其中的鍵是字段名,值是schema對(duì)象

content:

  application/json:

    schema:

      type: object

      properties:

        productName:

          type: string

        productPrice:

          type: number

parameters和requestBody
OAS提供了兩種機(jī)制來指定輸入數(shù)據(jù),parameters和request body(消息體).parameters用于標(biāo)識(shí)資源,request body用于提供資源的內(nèi)容


image.png

parameter對(duì)象: 在路徑項(xiàng)對(duì)象和操作對(duì)象中的parameters字段是一個(gè)包含parameter對(duì)象的數(shù)組,當(dāng)在路徑項(xiàng)對(duì)象中提供時(shí),parameters是與那一個(gè)路徑下的所有操作對(duì)象共享的

每一個(gè)parameter對(duì)象描述一個(gè)參數(shù),使用如下必須的字段:

  • in(string): 參數(shù)所處的位置
    可選值:
  • path,也就是說是位于路徑的一部分,也就是說我們?cè)谥付窂降臅r(shí)候,可以將路徑的一部分通過參數(shù)來代指,比如說路徑其實(shí)可以這樣指定, /users/{id} ,而且如果這樣指定了路徑的話,那么久必須通過parameter中的對(duì)應(yīng)一個(gè)名為id的參數(shù)來指定,同時(shí)需要注意的是,如果是路徑參數(shù)的話,那么該parameter對(duì)象中,必須有required: true 這一對(duì)屬性值
  • query: 就是附加在url的?后面的參數(shù)值
  • header: 作為自定義的HTTP header部分,注意它的名稱是大小寫敏感的
    name(string):參數(shù)名字,區(qū)分大小寫,在每個(gè)位置中必須唯一

額外的可選字段:

            description:描述信息,required(boolean)是否必填

parameter type:

大多時(shí)候,指定參數(shù)的數(shù)據(jù)類型都是通過schema對(duì)象(也就是在parameter對(duì)象中的schema字段)來指定。schema對(duì)象允許定義原子或者復(fù)雜的數(shù)據(jù)類型(數(shù)組或者對(duì)象)

parameters:

  • name: id

    in: query

    schema:

    type: integer

    minimum: 1

    maximum: 100

在更高級(jí)的場(chǎng)景中,會(huì)通過content字段來指定字段類型,它提供一個(gè)單入口(媒體類型到OAS媒體類型的)的映射。注意:schema或者content二者必須存在其一。它們不能同時(shí)出現(xiàn)

request body object:請(qǐng)求體是通過在操作對(duì)象中的requestBody字段來指定的,唯一的必填字段就是content

components和$ref

復(fù)用描述,很常見的情況是文檔太大以致于不好管理。為此我們可以通過復(fù)用機(jī)制來移除冗余的部分。

components對(duì)象:通過在根節(jié)點(diǎn)下的components字段定義,包含了要復(fù)用的對(duì)象的定義

image.png

當(dāng)然,并非所有的對(duì)象都是可以復(fù)用的,只有那些作為components對(duì)象的字段才可以列出來,比如schemas,responses,parameters

        組件對(duì)象中的每個(gè)字段都是一個(gè)將組件名稱與要重用的對(duì)象配對(duì)的映射。這些對(duì)象的類型必須與父字段匹配,例如,模式映射中的對(duì)象必須是模式對(duì)象;responses映射中的對(duì)象必須是response對(duì)象

引用對(duì)象:任意一個(gè)Components對(duì)象中的OpenAPI對(duì)象都可以通過引用對(duì)象來代替。

引用對(duì)象:通過 "$ref": "指向引用對(duì)象的uri資源路徑",來使用

  提供示例: example和examples

  api服務(wù)器servers:

servers對(duì)象提供了API的基礎(chǔ)URL,通過servers字段來定義,它是一個(gè)數(shù)組,它可以存在于根節(jié)點(diǎn)、路徑項(xiàng)對(duì)象或者操作對(duì)象中。

image.png

servers是一個(gè)數(shù)組,其中的每一個(gè)元素就是一個(gè)server對(duì)象,至少要有一個(gè)url字段,用于表示基礎(chǔ)路徑。一個(gè)可選的description字段,當(dāng)不同層級(jí)都有指定servers時(shí),只有層級(jí)最低的那一級(jí)會(huì)生效。例如:

servers:

- url: https://server1.com

paths:

  /users:

    get:

      servers:

      - url: https://server2.com
```yaml
        /users這個(gè)路徑實(shí)際應(yīng)該是追加在server2后面的,完整的請(qǐng)求url是 [https://server2.com](https://server2.com)/users

server url中可以包含變量,在url中通過{}分隔,這些變量必須在進(jìn)一步在server對(duì)象的variables中進(jìn)行配置。variables是一個(gè)對(duì)象,它是一個(gè)變量名和變量對(duì)象之間的映射關(guān)系。 

服務(wù)器變量對(duì)象有以下字段: 

default(string): 這是一個(gè)必填字段,如果沒有其他值要提供的話 

enum(字符串?dāng)?shù)組):如果存在的話,那么這個(gè)數(shù)組就會(huì)列出該變量的合法值,默認(rèn)值也必須出現(xiàn)在其中 

description: 該字段的描述 

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容