빠른 비교
{
"type": "object",
"properties": {
"status": {
"enum": ["draft", "review", "published"]
},
"tags": {
"type": "array",
"items": { "type": "string" }
}
}
}갈리는 기준
items는 array의 모든 항목이 따라야 할 규칙을 정의한다 — 선언하지 않으면 어떤 타입도 허용된다
JSON Schema에서 items는 array의 모든 항목에 동일하게 적용되는 sub-schema입니다. "items": { "type": "string" }은 배열 항목이 모두 string이어야 함을 요구합니다. items를 선언하지 않으면 배열 항목의 타입이 검증되지 않아, 소비자가 string[]이라고 가정하고 읽은 값이 실제로는 number나 object일 수 있습니다. minItems, maxItems로 배열 길이를 제한하거나, uniqueItems: true로 중복을 차단하는 것도 자주 쓰이는 조합입니다.
{
"type": "array",
"items": { "type": "string" },
"minItems": 1,
"uniqueItems": true
}위치별로 의미가 다른 배열은 prefixItems로 tuple을 정의한다 — 모든 항목이 같은 규칙을 따르는 배열과 구분해야 한다
items는 모든 항목에 단일 규칙을 적용하는 homogeneous array를 위한 것입니다. 위치마다 다른 타입을 기대하는 tuple 형태라면 prefixItems를 사용합니다. prefixItems는 배열이며, 각 index에 대응하는 sub-schema를 순서대로 선언합니다. 예를 들어 [latitude, longitude] 형태라면 0번째는 number, 1번째도 number이지만 각각 범위 제약이 다를 수 있습니다. prefixItems 이후 추가 항목 허용 여부는 items: false로 차단하거나, sub-schema로 추가 항목 규칙을 정의할 수 있습니다.
{
"type": "array",
"prefixItems": [
{ "type": "number", "minimum": -90, "maximum": 90 },
{ "type": "number", "minimum": -180, "maximum": 180 }
],
"items": false
}enum은 허용 값의 집합을 고정한다 — 상태값, 코드 목록처럼 선택지가 정해진 필드에 필수적이다
enum은 해당 위치에서 허용되는 값의 완전한 목록을 선언합니다. 상태(draft, review, published), 역할(admin, editor, viewer), 국가 코드처럼 값의 범위가 고정된 필드에 사용합니다. enum에 없는 값이 들어오면 즉시 검증 실패로 잡혀, 잘못된 상태값이 시스템에 전파되는 것을 막습니다. enum은 타입을 따로 선언하지 않아도 되며, string과 number 혼합 목록도 가능합니다. 그러나 값의 범위가 자주 바뀐다면 enum보다 서버 측 검증이 더 유연할 수 있습니다.
const는 단일 고정값을 선언한다 — enum 하나짜리보다 의도가 더 명확하다
const는 해당 필드의 값이 항상 특정 하나의 값이어야 함을 선언합니다. "const": "v2"처럼 쓰면 enum: ["v2"]와 동일한 검증 효과지만, "이 값은 변하지 않는 상수"라는 의도가 schema를 읽는 사람에게 더 명확하게 전달됩니다. 조합 schema에서 특정 분기를 식별하는 discriminator 역할로 자주 쓰입니다. 예를 들어 type 필드의 값에 따라 다른 sub-schema를 적용하는 oneOf 패턴에서 const로 분기를 구분합니다.
{
"oneOf": [
{
"properties": { "type": { "const": "circle" }, "radius": { "type": "number" } }
},
{
"properties": { "type": { "const": "rect" }, "width": { "type": "number" } }
}
]
}{
"type": "object",
"properties": {
"status": {
"enum": ["draft", "review", "published"]
},
"tags": {
"type": "array",
"items": { "type": "string" }
}
}
}선택 기준
| 상황 | 적합한 선택 |
|---|---|
| 모든 항목이 같은 타입인 배열 | items sub-schema |
| 위치별로 타입이 다른 배열 | prefixItems |
| 허용 값 집합을 고정해야 할 때 | enum |
| 단일 고정값을 선언할 때 | const |
| tuple 뒤 추가 항목을 막아야 할 때 | prefixItems + items: false |
주의할 점
items를 선언하지 않으면 배열 항목 타입이 전혀 검증되지 않습니다. enum 목록은 schema
변경 없이 새 값을 추가할 수 없으므로, 값의 범위가 자주 바뀌는 필드라면 서버 측 검증이
더 유연합니다. prefixItems와 items: false 조합으로 tuple을 닫지 않으면 선언된 항목
이후에 어떤 값도 추가될 수 있습니다.
{
"type": "array",
"prefixItems": [
{ "type": "number" },
{ "type": "number" }
]
}prefixItems만 두고 items: false를 빼면, 선언된 두 값 뒤에 추가 항목이 더 붙어도 통과할 수 있습니다. tuple을 닫을지 열어 둘지를 함께 결정해야 합니다.
또한 값 집합이 자주 바뀌는 필드에 enum을 과하게 쓰면 schema 배포가 곧 제품 배포가 됩니다. "정말 고정된 목록인가"를 먼저 확인하는 편이 좋습니다.
참고 링크
2 sources