OpenAPI에서 oneOf 이해하기 (혼란 없이)
Source: Dev.to
Introduction
OpenAPI로 API를 설계할 때 oneOf는 겁을 주는 경우가 많습니다. 강력하지만 특히 PATCH 엔드포인트에서 잘못 사용하기 쉽습니다. 간단히 풀어보겠습니다.
What oneOf Means in OpenAPI (JSON Schema)
- 요청 본문은 목록에 있는 스키마 중 정확히 하나와 일치해야 합니다.
- 하나도 아니어서는 안 됩니다.
- 정확히 하나만.
Example
schema:
oneOf:
- $ref: '#/components/schemas/InverterPatch'
- $ref: '#/components/schemas/EVPatch'
- $ref: '#/components/schemas/EVCSPatch'
이는 OpenAPI에 “페이로드는 이 스키마 중 정확히 하나에 맞아야 한다”는 뜻을 전달합니다.
oneOf Is Tricky with PATCH
PATCH 요청은 부분 업데이트입니다. 클라이언트는 보통 몇 개의 필드만 보냅니다.
다음과 같은 페이로드를 생각해 보세요:
{
"reverseFlow": true
}
reverseFlow가 InverterPatch와 EVCSPatch 모두에 존재한다면, 이 페이로드는 두 개 이상의 스키마와 일치하게 됩니다.
🚫 Result: 검증 실패, oneOf는 정확히 하나의 매치를 요구하기 때문입니다.
Using a Discriminator to Resolve Ambiguity
discriminator:
propertyName: type
이제 클라이언트는 다음과 같이 보냅니다:
{
"type": "inverter",
"reverseFlow": true
}
OpenAPI는 즉시 다음을 알게 됩니다:
type = inverter→InverterPatch사용 → 검증 성공.
💡 디스크리미네이터는 OpenAPI에게 어떤 스키마로 검증할지 알려줍니다.
When to Use oneOf (with a Discriminator)
- 여러 스키마가 있을 때.
- 일부 필드가 겹칠 때.
- 클라이언트가 부분 업데이트를 보낼 수 있을 때.
- 백엔드 로직이 아니라 OpenAPI 수준에서 검증하고 싶을 때.
When to Avoid oneOf
- 스키마 간 선택을 OpenAPI가 할 필요가 없을 때.
- 백엔드가 이미 리소스 유형을 알고 있을 때.
- 타입별 규칙을 런타임에 검증해도 괜찮을 때.
이 경우, 선택적 필드를 가진 단일 PATCH 스키마가 더 간단하고 종종 더 좋습니다.
Summary
oneOf= 정확히 하나의 스키마와 일치해야 함.- 겹치는 필드 +
PATCH= 모호성 발생. - 디스크리미네이터가 그 모호성을 해소함.
- 실제로 스키마 선택이 필요하지 않다면
oneOf를 사용하지 마세요.
올바르게 사용하면 oneOf는 API를 더 안전하고 자체 문서화하게 만들고, 잘못 사용하면 PATCH 엔드포인트가 고통스러워집니다.