OpenAPI (especially v3.1) does support conditional request/response schemas based on parameters in the payload — using oneOf
, anyOf
, discriminator
, or JSON Schema if
/ then
/ else
(in v3.1 only).
Example Scenarios
Let’s say your request body has a field like "type": "email"
or "type": "sms"
, and the shape of the rest of the payload depends on it.
Solution 1: discriminator
(Best for mutually exclusive types)
This is clean and well-supported in tools like Swagger UI:
requestBody:
required: true
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/EmailRequest'
- $ref: '#/components/schemas/SmsRequest'
discriminator:
propertyName: type
mapping:
email: '#/components/schemas/EmailRequest'
sms: '#/components/schemas/SmsRequest'
components:
schemas:
EmailRequest:
type: object
required: [type, email]
properties:
type:
type: string
enum: [email]
email:
type: string
format: email
SmsRequest:
type: object
required: [type, phone]
properties:
type:
type: string
enum: [sms]
phone:
type: string
🎯 This is good when the payload changes entirely depending on a
type
.
Solution 2: if/then/else
(Only in OpenAPI 3.1)
If you’re using OpenAPI 3.1, which supports full JSON Schema, you can do this:
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
type:
type: string
allOf:
- if:
properties:
type:
const: email
then:
required: [email]
properties:
email:
type: string
format: email
- if:
properties:
type:
const: sms
then:
required: [phone]
properties:
phone:
type: string
⚠️ This is powerful but not widely supported in Swagger UI yet.
Solution 3: oneOf
without discriminator
If you can’t use discriminator
, you can still use oneOf
:
requestBody:
content:
application/json:
schema:
oneOf:
- type: object
required: [type, email]
properties:
type:
type: string
enum: [email]
email:
type: string
- type: object
required: [type, phone]
properties:
type:
type: string
enum: [sms]
phone:
type: string
Downside: Swagger UI can’t infer which schema to use unless you also give a discriminator
.
Conditional Response Schema?
You can also vary the response based on a request parameter (like type
) using:
oneOf
inresponses.[status].content.application/json.schema
- Or just define multiple response examples, if it’s not programmatically deducible.
🔚 Summary
Approach | Best For | OpenAPI Version | UI Support |
---|---|---|---|
discriminator + oneOf |
Polymorphic request bodies | 3.0+ | ✅ Swagger UI |
if/then/else |
Complex conditional logic | 3.1 only | ⚠️ Partial |
oneOf without discriminator |
Simpler cases | 3.0+ | ⚠️ Limited |
Multiple examples |
Optional clarity | 3.0+ | ✅ |