Postman Spec Hub が OpenAPI 2.0 / 3.1 に対応したので試してみた
過去新しいくリリースされたPostman SpecHubを以下の記事で試してみました。
OpenAPI3.0 / Async2.0 準拠のAPI諸元(設計図)を管理することが可能でそこから必要に応じてコレクション(テスト用APIコール)を作成できる機能です。
2025年11月5日にSpecHubが新たに OpenAPI2.0 / 3.1 の諸元に対応しました。2.0は今から新規で作成することは少ないかと思いますのでこの記事では3.1を試していきます。
OpenAPI 3.1
OpenAPI 3.1 では3.0に加えて主に以下の変更が入っています。
JSON Schema 2020-12にフル準拠。
3.0でももちろんJSONには対応していたのですがあくまで独自解釈で対応している、という状態でしたが、3.1ではJSON Schema 2020-12に正式対応したことにより表現が統一されました。
条件によるバリデーション
上記によりPostされるボディなどに対して条件によるバリデーションが接敵出るようになりました。
if / then / else 構文を用いて条件によって必要なパラメータ条件を変動させることが可能になりました。
schema:
$schema: "https://json-schema.org/draft/2020-12/schema"
type: object
properties:
status:
type: string
enum: [pending, paid]
notes:
type: ["string", "null"]
payment:
type: ["object", "null"]
properties:
method:
type: string
enum: [card, bank]
transactionId:
type: string
required: ["method"]
required: ["status"]
# 🔍 ここが3.1で使える if / then / else 構文
if:
properties:
status: { const: paid }
then:
required: ["payment"]
else:
properties:
payment: { type: "null" }
unevaluatedProperties: false
例えばこのサンプルですとstatusがpaidの場合、paymentパラメータは必須になります。一方statusがpaid以外の場合、paymentパラメータはnull固定になります。
null の取り扱いの明確化
3.0ではnullable: trueとしてnullを取り扱っていましたが、3.1ではtype: ["string","null"]としてユニオン型で定義されるようになりました。
詳細はこちらの公式サイトを参照してください。
さっそくやってみる
ではさっそくOpenAPI3.1ベースのAPI諸元をyamlで作成して投入してみます。
新たに選択できるようになったOpenAPI3.1を選択します。
以下のyamlを貼り付けて保存します。
openapi: 3.1.0
info:
title: Sample 3.1-only Features API
version: 1.0.2
description: >
OpenAPI 3.1 で追加された機能を使ったデモAPI。
- JSON Schema 2020-12準拠
- if/then/else, unevaluatedProperties, dependentSchemas
- webhooks, components.pathItems
- ユニオン型によるnull許容
jsonSchemaDialect: "https://json-schema.org/draft/2020-12/schema"
servers:
- url: https://kameda.requestcatcher.com/
paths:
/orders/{orderId}:
$ref: "#/components/pathItems/orderById"
/orders:
post:
summary: Create an order
description: 新しい注文を作成します。
requestBody:
required: true
content:
application/json:
schema:
$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "https://kameda.requestcatcher.com/schemas/create-order"
type: object
properties:
status:
type: string
enum: [pending, paid]
notes:
type: ["string", "null"]
payment:
type: ["object", "null"]
properties:
method:
type: string
enum: [card, bank]
transactionId:
type: string
required: ["method"]
required: ["status"]
if:
properties:
status: { const: paid }
then:
required: ["payment"]
else:
properties:
payment: { type: "null" }
unevaluatedProperties: false
examples:
pending:
summary: 注文保留状態
value:
{
"status": "pending",
"notes": "call me before shipping",
"payment": null
}
paid_card:
summary: 支払い完了(カード)
value:
{
"status": "paid",
"notes": "please deliver soon",
"payment": {
"method": "card",
"transactionId": "tr_abc123"
}
}
paid_bank:
summary: 支払い完了(銀行振込)
value:
{
"status": "paid",
"notes": null,
"payment": {
"method": "bank",
"transactionId": "bank_20251105_001"
}
}
minimal:
summary: 最小構成(status のみ)
value:
{ "status": "pending" }
responses:
"201":
description: Created
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
"400":
description: Bad Request
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
components:
pathItems:
orderById:
parameters:
- name: orderId
in: path
required: true
description: Order identifier
schema:
type: string
get:
summary: Get order by ID
responses:
"200":
description: OK
content:
application/json:
schema:
$ref: "#/components/schemas/Order"
"404":
description: Not Found
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
schemas:
Order:
$schema: "https://json-schema.org/draft/2020-12/schema"
$id: "https://kameda.requestcatcher.com/schemas/order"
type: object
properties:
id: { type: string }
status:
type: string
enum: [pending, paid, shipped, cancelled]
notes:
type: ["string", "null"]
delivery:
type: object
properties:
method:
type: string
enum: [pickup, courier]
address:
type: ["object", "null"]
properties:
line1: { type: string }
city: { type: string }
postalCode: { type: string }
required: ["line1", "city", "postalCode"]
required: ["method"]
required: ["id", "status"]
dependentSchemas:
delivery:
properties:
delivery:
type: object
if:
properties:
method: { const: courier }
then:
required: ["address"]
else:
properties:
address: { type: "null" }
unevaluatedProperties: false
Error:
$schema: "https://json-schema.org/draft/2020-12/schema"
type: object
properties:
code: { type: integer }
message: { type: string }
cause: { type: ["string", "null"] }
required: ["code", "message"]
unevaluatedProperties: false
webhooks:
orderCreated:
post:
summary: Webhook when an order is created
requestBody:
required: true
content:
application/json:
schema:
$schema: "https://json-schema.org/draft/2020-12/schema"
allOf:
- $ref: "#/components/schemas/Order"
unevaluatedProperties: false
responses:
"200":
description: Acknowledge

Generate Collectonをクリックします。

APIコールが一つの複数のサンプルが作成されました。

ボディでは以下の様に条件ごとにパラメータが変わっており、その条件分岐ごとにサンプルが自動で作成されています。


Discussion