Summary#
OpenAPI의 oneOf / anyOf / allOf, discriminator, nullable, 순환 참조, additionalProperties 조합은 명세상 표현력은 높지만 코드 생성기와 런타임 validator 사이에서 자주 실패한다. 특히 TypeScript, Java, Kotlin SDK 생성에서는 JSON Schema의 검증 의미론과 각 언어의 타입 시스템, 직렬화 라이브러리, 상속 모델이 정확히 맞지 않아 “명세는 유효하지만 생성된 코드가 컴파일되지 않거나, 컴파일은 되지만 잘못 검증/역직렬화되는” 문제가 발생한다.
실무적으로 안전한 설계 원칙은 다음과 같다: oneOf에는 명확한 판별 필드와 상호 배타적인 스키마를 두고, allOf를 “상속”처럼 과용하지 않으며, OpenAPI 3.0의 nullable과 OpenAPI 3.1의 JSON Schema 방식 type: ["string", "null"]를 혼용하지 않는다. 또한 생성 대상 언어별 generator 옵션과 validator의 JSON Schema draft 지원 범위를 문서화해야 한다.
Key Points#
oneOf는 “하나만 정확히 매칭”되어야 한다- JSON Schema 의미론에서
oneOf는 후보 스키마 중 정확히 하나만 통과해야 한다. - 여러 후보가 동시에 통과할 수 있으면 validator는 실패해야 하지만, 일부 코드 생성기는 이를 단순 union type, sealed class, interface hierarchy 등으로 매핑하면서 런타임 검증을 생략하거나 약화할 수 있다.
-
예: 두 하위 스키마가 모두
type: object이고 필수 필드 차이가 작거나additionalProperties: true이면 동일 payload가 복수 스키마에 매칭될 수 있다. -
discriminator는 validation 자체를 대체하지 않는다 - OpenAPI의
discriminator는 다형성 역직렬화와 스키마 선택을 돕는 힌트에 가깝다. discriminator.propertyName이 있다고 해서oneOf후보들이 자동으로 상호 배타적이 되지는 않는다.- 안전하게 쓰려면 각 하위 스키마에 discriminator 필드를
required로 두고, 가능한 경우const또는 enum 단일값에 준하는 제약을 둬야 한다. -
OpenAPI 3.0은 JSON Schema 완전 호환이 아니므로
const같은 키워드 사용 가능성은 버전과 도구 지원을 확인해야 한다. -
allOf를 상속처럼 쓰면 언어별 생성 결과가 갈린다 - OpenAPI 문서에서는
allOf를 composition에 사용할 수 있지만, 많은 도구가 이를 class inheritance처럼 해석한다. - Java/Kotlin에서는 부모 클래스, 인터페이스, composition wrapper 등 generator별로 결과가 달라질 수 있다.
- TypeScript에서는 intersection type으로 비교적 자연스럽게 보일 수 있으나, 런타임 validator나 serializer가 동일 의미를 보장하지 않을 수 있다.
-
특히
allOf안에서 같은 property가 서로 다른 타입/제약으로 반복 정의되면 validator는 교집합으로 해석하지만 generator는 충돌하거나 한쪽 정의를 덮어쓸 수 있다. -
OpenAPI 3.0의
nullable과 OpenAPI 3.1의 JSON Schema null 표현은 다르다 - OpenAPI 3.0에서는
nullable: true가 별도 확장처럼 사용된다. - OpenAPI 3.1은 JSON Schema 2020-12 계열과 더 가까워져
type: ["string", "null"]같은 표현이 가능하다. - 코드 생성기는 3.0/3.1 지원 수준이 다르며,
nullable,required, optional property의 조합을 언어별로 다르게 매핑한다. -
TypeScript에서는
undefined와null의 차이, Java/Kotlin에서는 nullable type, Optional, boxed primitive, Jackson/Moshi/Gson 설정 차이가 문제를 만든다. -
additionalProperties는 다형성 매칭을 쉽게 흐린다 - 객체 스키마에서
additionalProperties가 열려 있으면 예상치 못한 필드가 허용되어oneOf후보 간 구분이 약해진다. oneOf후보가 모두 느슨한 object schema라면 동일 객체가 여러 후보를 통과할 수 있다.-
generator는 map-like model, free-form object, typed properties를 섞어 생성하면서 언어별 타입 안정성이 낮아질 수 있다.
-
순환 참조와 다형성의 결합은 생성기 실패 가능성이 높다
$ref순환은 트리 구조, graph 구조, parent-child 관계를 표현할 때 필요하지만,oneOf/allOf와 결합되면 생성 코드에서 무한 import, recursive type alias, Jackson subtype 등록 누락, Kotlin sealed hierarchy 문제 등을 만들 수 있다.- TypeScript generator는 recursive interface/type alias 처리 방식에 따라 컴파일 가능성이 달라진다.
-
Java/Kotlin generator는 역직렬화 annotation, no-arg constructor, abstract class/interface 인스턴스화 문제에 민감하다.
-
validator와 code generator는 같은 명세를 다르게 해석할 수 있다
- validator는 JSON Schema 의미론을 중심으로 작동한다.
- code generator는 언어 타입, 런타임 serializer, generator 옵션, 템플릿에 따라 모델을 만든다.
-
따라서 “OpenAPI 문서가 spec-valid”하다는 사실은 “생성 SDK가 안전하게 작동한다”는 보장이 아니다.
-
권장 설계 패턴
- 다형성
oneOf에는 항상 명확한 discriminator 필드를 둔다. - 각 subtype은 discriminator 값을 필수로 갖게 한다.
- subtype 간 required property set이 겹치지 않도록 한다.
additionalProperties: false또는 제한된 schema를 검토한다.allOf는 공통 속성 재사용에는 쓰되, 복잡한 다중 상속처럼 쓰지 않는다.- OpenAPI 3.0과 3.1 문법을 혼합하지 않는다.
- codegen 대상 언어별 smoke test를 CI에 넣는다.
- validator 테스트와 generated SDK serialization/deserialization 테스트를 분리해서 둔다.
Cautions#
- 현재 환경에서는 사용자가 요청한 일반 공개 웹 WebSearch/WebFetch 도구가 제공되지 않아, 공개 웹 원문을 실시간으로 검색·검증하지 못했다. 아래 Sources는 공개적으로 알려진 표준 문서와 도구 문서 URL 중심의 초안용 출처다.
- 특정 generator bug는 버전 의존성이 크다. OpenAPI Generator, Swagger Codegen, Kiota, NSwag, openapi-typescript 등 도구별 최신 동작은 별도 확인이 필요하다.
- OpenAPI 3.0과 3.1은 JSON Schema 호환성 수준이 다르므로, 한 버전에서 안전한 패턴이 다른 버전에서도 동일하게 동작한다고 가정하면 안 된다.
discriminator지원은 validator보다 code generator와 serializer에서 더 큰 차이를 보인다. 특히 Java/Kotlin의 Jackson annotation, TypeScript의 runtime type guard 생성 여부는 도구별로 다르다.additionalProperties: false는 엄격성을 높이지만 API 진화성에는 부담을 줄 수 있다. backward compatibility 요구와 함께 판단해야 한다.oneOfambiguity는 명세상 validation 실패가 맞을 수 있으나, 일부 클라이언트 SDK는 이를 compile-time union으로만 표현하고 runtime ambiguity를 드러내지 않을 수 있다.
Sources#
- https://spec.openapis.org/oas/v3.0.3.html#composition-and-inheritance-polymorphism
- https://spec.openapis.org/oas/v3.0.3.html#discriminator-object
- https://spec.openapis.org/oas/v3.1.0.html#discriminator-object
- https://spec.openapis.org/oas/v3.1.0.html#schema-object
- https://json-schema.org/draft/2020-12/json-schema-core.html
- https://json-schema.org/draft/2020-12/json-schema-validation.html
- https://swagger.io/docs/specification/v3_0/data-models/oneof-anyof-allof-not/
- https://swagger.io/docs/specification/v3_0/data-models/inheritance-and-polymorphism/
- https://openapi-generator.tech/docs/generators/typescript-fetch/
- https://openapi-generator.tech/docs/generators/java/
- https://openapi-generator.tech/docs/generators/kotlin/
Sagwan Revalidation 2026-05-04T18:06:34Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드생성 실패 모드는 현재도 유효하다.
Sagwan Revalidation 2026-05-05T18:35:15Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드젠 실패 모드는 현재 practice에도 부합함
Sagwan Revalidation 2026-05-06T18:41:14Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드생성 실패 양상은 여전히 유효하다.
Related#
- discriminator 코드생성 호환성 실패 모드
- OpenAPI Backward Compatibility Diff Rules and Client Generation Failure Modes
Sagwan Revalidation 2026-05-07T19:03:20Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드생성 실패 모드 설명은 현재도 유효함
Sagwan Revalidation 2026-05-08T19:07:32Z#
- verdict:
ok - note: 현재 OpenAPI 3.0/3.1 및 주요 codegen 관행과 여전히 부합함
Sagwan Revalidation 2026-05-09T19:21:49Z#
- verdict:
ok - note: OpenAPI 조합/코드생성 실패 모드와 권장안이 현재도 유효합니다.
Sagwan Revalidation 2026-05-10T19:27:36Z#
- verdict:
ok - note: OAS 3.0/3.1 차이와 codegen 실패 모드 권장은 현재도 유효합니다.
Sagwan Revalidation 2026-05-11T19:38:47Z#
- verdict:
ok - note: [chatgpt HTTP 401] {
Sagwan Revalidation 2026-05-12T20:19:35Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드생성 실패 원칙은 현재도 유효하다.
Sagwan Revalidation 2026-05-13T20:40:35Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드 생성 실패 모드 설명이 현재 관행과 부합함
Sagwan Revalidation 2026-05-14T21:12:16Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드 생성기 한계에 대한 권장안은 여전히 유효함
Sagwan Revalidation 2026-05-15T21:41:49Z#
- verdict:
ok - note: 일반 원칙 중심이며 OpenAPI 3.0/3.1 및 codegen 주의점이 여전히 유효함
Sagwan Revalidation 2026-05-16T21:57:15Z#
- verdict:
ok - note: OpenAPI 조합/코드생성 실패 모드와 권장안이 현재도 유효함
Sagwan Revalidation 2026-05-17T22:19:33Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드 생성 실패 양상은 여전히 실무적으로 유효함
Sagwan Revalidation 2026-05-18T22:46:49Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드생성 실패 양상은 현재도 유효하다.
Sagwan Revalidation 2026-05-19T23:09:19Z#
- verdict:
ok - note: OAS 3.0/3.1 조합·codegen 실패 양상과 권장안은 여전히 유효함
Sagwan Revalidation 2026-05-20T23:45:37Z#
- verdict:
ok - note: OpenAPI 3.0/3.1 조합·코드생성 실패 모드 설명은 현재도 유효함
Sagwan Revalidation 2026-05-22T00:08:34Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드생성 실패 모드는 여전히 유효한 실무 이슈다.
Sagwan Revalidation 2026-05-23T00:19:22Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드 생성 실패 모드는 현재도 유효하다.
Sagwan Revalidation 2026-05-24T00:53:10Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드 생성 실패 모드는 여전히 유효하다.
Sagwan Revalidation 2026-05-25T01:13:08Z#
- verdict:
ok - note: 핵심 권장과 실패 모드는 현재 OpenAPI/codegen practice에도 유효함
Sagwan Revalidation 2026-05-26T01:56:44Z#
- verdict:
ok - note: OpenAPI 합성/코드생성 실패 모드는 현재 관행과도 부합한다.
Sagwan Revalidation 2026-05-27T02:01:18Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드생성 실패 모드 설명은 여전히 유효함
Sagwan Revalidation 2026-05-28T03:06:06Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 codegen 실패 양상은 현재도 유효하다.
Sagwan Revalidation 2026-05-29T03:09:52Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드 생성 실패 양상은 현재도 유효하다.
Sagwan Revalidation 2026-05-30T03:39:31Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 codegen 한계 설명은 현재도 실무적으로 유효함
Sagwan Revalidation 2026-05-31T04:14:16Z#
- verdict:
ok - note: OpenAPI 조합 스키마의 코드생성 실패 모드는 여전히 실무적으로 유효함
Sagwan Revalidation 2026-06-01T07:53:31Z#
- verdict:
ok - note: OpenAPI 조합/코드생성 실패 모드와 권장안은 현재도 유효하다.
Sagwan Revalidation 2026-06-02T08:51:21Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 codegen 위험 설명이 현재 practice와도 부합함
Sagwan Revalidation 2026-06-03T09:40:23Z#
- verdict:
ok - note: OpenAPI 조합/코드생성 한계와 권장안이 현재 practice와 부합함
Sagwan Revalidation 2026-06-04T10:08:09Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드 생성 실패 모드는 현재도 유효하다.
Sagwan Revalidation 2026-06-05T10:28:35Z#
- verdict:
ok - note: OpenAPI 조합 스키마와 코드 생성 실패 양상은 현재도 유효하다.