1. 概述
在本教程中,我們將學習如何使用 OpenAPI,通過 JSON 對象作為查詢參數進行操作。
2. OpenAPI 2 中的查詢參數
OpenAPI 2 不支持將對象作為查詢參數;僅支持原始值和原始值的數組。
因此,我們應該將 JSON 參數定義為 字符串。
為了演示這一點,讓我們定義一個名為 params 的參數為 字符串,即使我們將在後端將其解析為 JSON:
swagger: "2.0"
...
paths:
/tickets:
get:
tags:
- "tickets"
summary: "Send an JSON Object as a query param"
parameters:
- name: "params"
in: "path"
description: "{\"type\":\"foo\",\"color\":\"green\"}"
required: true
type: "string"
因此,而不是:
GET http://localhost:8080/api/tickets?type=foo&color=green我們將會:
GET http://localhost:8080/api/tickets?params={"type":"foo","color":"green"}3. OpenAPI 3 中的查詢參數
OpenAPI 3 引入了對查詢參數作為對象的支持。
為了指定 JSON 參數,我們需要在定義中添加 content 部分,其中包含 MIME 類型和模式:
openapi: 3.0.1
...
paths:
/tickets:
get:
tags:
- tickets
summary: Send an JSON Object as a query param
parameters:
- name: params
in: query
description: '{"type":"foo","color":"green"}'
required: true
schema:
type: object
properties:
type:
type: "string"
color:
type: "string"
我們的請求現在看起來像這樣:
GET http://localhost:8080/api/tickets?params[type]=foo¶ms[color]=green實際上,它仍然可以看起來像這樣:
GET http://localhost:8080/api/tickets?params={"type":"foo","color":"green"}第一個選項允許我們使用參數驗證,這將在請求發出之前告知我們是否存在問題。
第二個選項則犧牲了這一點,以換取後端更大的控制權以及 OpenAPI 2 的兼容性。
4. URL 編碼
需要注意的是,我們決定將請求參數作為 JSON 對象傳輸時,必須對參數進行 URL 編碼,以確保安全傳輸。
因此,要發送以下 URL:
GET /tickets?params={"type":"foo","color":"green"}我們實際上會做:
GET /tickets?params=%7B%22type%22%3A%22foo%22%2C%22color%22%3A%22green%22%7D5. 限制
請務必注意,將 JSON 對象作為查詢參數傳遞存在以下限制:
- 安全性降低
- 參數長度有限
例如,我們放置在查詢參數中的數據越多,就越容易出現在服務器日誌中,從而導致敏感數據泄露的風險越高。
此外,單個查詢參數的長度不能超過 2048 個字符。 毫無疑問,我們都能想象到 JSON 對象大於此值的場景。 實際上,對 JSON 字符串進行 URL 編碼,會將我們的有效負載限制在約 1000 個字符左右。
一種解決方法是使用請求體發送更大的 JSON 對象。 這樣可以同時解決安全問題和 JSON 長度限制。
實際上,GET 和 POST 都支持這種方法。 使用 GET 發送請求體的原因是為了保持我們 API 的 RESTful 語義。
當然,這有點不尋常,並非所有庫都支持它。 例如,某些 JavaScript HTTP 庫不允許 GET 請求具有請求體。
總而言之,這是一個語義與通用兼容性之間的權衡。
6. 結論
總結來説,在本文中,我們學習瞭如何使用 OpenAPI 將 JSON 對象指定為查詢參數。此外,我們還觀察了這些參數對後端的影響。