Post

Json Schema

목차


Json Schema

  • key-value로 이루어진 Json Data가 규칙에 맞게 작성되었는지 유효성을 검사를 제공
  • 검증 내용
    • data type이 정확한지
    • 필수로 받아와야 하는 데이터가 Json 내에 있는지
    • data가 정해진 범위 내에 있는지 (size, length, min, max 등)

출처

키워드

메타데이터

스키마의 기본 정보를 나타내는 메타데이터(metadata) 키워드이다. Json Schema의 구조를 설명하는 키워드로써 유효성 검사에는 사용되지 않는다. 모든 필드가 필수 요소는 아니지만 다른 사용자가 해당 Json Schema를 이해하는 데 도움이 될 수 있다.

keyword설명
title스키마 이름
description스키마 설명
example스키마 검증에 통과하는 예시 (배열 형태)
$comment특정 스키마에 주석을 남길 때 사용
1
2
3
4
5
6
{
  "title": "User",
  "description": "유저 정보",
  "example": ["firstName", "lastName"],
  "$comment": "주석",
}

Json Schema 검증 조건 키워드

JSON Schema는 JSON 포맷이다. 데이터의 유효성을 검사하기 위한 여러 가지 검증 키워드가 존재한다. 아래 키워드들을 조합해서 JSON 포맷을 검증할 수 있다.

keyword설명
type필드의 유효한 데이터 타입을 명시
required반드시 포함되어야 하는 속성을 배열 형태로 표현
properties객체(object) 타입인 경우 속성을 표기
minLength문자열의 최소 길이
maxLength문자열의 최대 길이
minItems배열 요소의 최소 개수
maxItems배열 요소의 최대 개수
pattern정규 표현식과 일치한 문자열

JSON 스키마의 데이터 타입

데이터 타입설명예시
number모든 숫자 형태0, 1, -1, 0.1, -1.23
integer정수 형태0, 1, -1
string문자열/텍스트 형태"asdf"
array배열 형태[ "a", 0, null ]
object키/값 형태로 구성된 문자열{ "lastName": "Lee" }
booleantrue 또는 falsetrue, false
null값이 없는 경우 nullnull

숫자 타입

모든 숫자 타입(실수, 정수)을 검사한다.

1
2
3
{
  "type": "number"
}

정수 타입인지 검사한다.

1
2
3
{
  "type": "integer"
}

세부 데이터 검증

키워드설명타입
multipleOf배수 검증int
minimum최솟값 이상 (>=)int
maximum최댓값 이하 (<=)int
exclusiveMinimumtrue 시 최솟값의 초과 데이터를 검사한다. (>)
false 시 최솟값 이상의 데이터를 검사한다. (>=) 디폴트 값은 false 이다.
boolean
exclusiveMaximumtrue 시 최댓값의 미만 데이터를 검사한다. (<)
false 시 최댓값 이하의 데이터를 검사한다. (<=) 디폴트 값은 false 이다.
boolean

2의 배수인지 검사한다.

1
2
3
4
{
  "type": "integer",
  "multipleOf", 2
}

0 이상 100 이하의 정수를 검사하는 예시이다.

1
2
3
4
5
{
  "type": "integer",
  "minimum": 0,
  "maximum": 100
}

0 초과, 100 미만(1 이상 99 이하)의 정수를 검사하는 예시이다.

1
2
3
4
5
6
7
{
  "type": "integer",
  "minimum": 0,
  "maximum": 100,
  "exclusiveMinimum": true,
  "exclusiveMaximum": true
}

문자열 타입

1
2
3
{
  "type": "string"
}

세부 데이터 검증

키워드설명타입
minLength해당 길이 이상의 문자열 검증int
maxLength해당 길이 이하의 문자열 검증int
pattern정규표현식과 일치하는 문자열 검증string (정규표현식)
format문자열 포맷을 검증string

1이상 10 이하의 문자열을 검증하는 예시이다.

1
2
3
4
5
{
  "type": "string",
  "minLength": 1,
  "maxLength": 10
}

최소 1글자 이상이면서 소문자 영문을 검증하는 예시이다.

1
2
3
4
{
  "type": "string",
  "pattern": "^[a-z]+$"
}

문자열 포맷을 검사한다.

포맷이름포맷
date-time2000-01-01T00:00:00+09:00
time00:00:00+09:00
date2000-01-01
emailtest@dev.iasdf.com
hostnamedev.iasdf.com

문자열이고 날짜인지 검사
날짜 타입은 년도 4자리, 월 2자리, 일 2자리로 구성된다.

년도 : 0001 ~ 9999 월 : 01 ~ 1월 일 : 01 ~ 31일 (월 및 윤년에 따라 검증 값이 달라질 수 있음.)

1
2
3
4
{
  "type": "string",
  "format": "date"
}

문자열이고 시간인지 검사
시간 타입은 24시 포맷을 가지고 있으며 시 2자리, 분 2자리, 초 2자리로 구성된다.
시 : 00 ~ 23
분 : 00 ~ 59
초 : 00 ~ 59

시간대의 경우 옵션값이다
시간대의 시 : 00 ~ 99
시간대의 분 : 00 ~ 59

1
2
3
4
{
  "type": "string",
  "format": "time"
}

배열 검증

1
2
3
{
  "type": "array"
}

세부 데이터 검증

키워드설명타입
items배열의 요소 타입 검증object or array
minItems배열이 해당 개수 이상인지 검증int
maxItems배열이 해당 개수 이하인지 검증int
uniqueItems배열의 요소가 중복되지 않는지 검증boolean

배열이 정수 타입인지 검사한다.

1
2
3
4
5
6
{
  "type": "array",
  "items": {
    "type": "integer"
  }
}

배열이 정수 또는 문자열 타입인지 검사한다.

1
2
3
4
5
6
{
  "type": "array",
  "items": {
    "type": [ "integer", "string" ]
  }
}

배열 요소는 무조건 3개여야 하며
첫번째 요소는 정수 타입이어야 하고
두번째 요소는 문자열 타입이어야 하고 최소 길이값이 5 이상이어야 하며
세번째 요소는 문자열 타입이어야 한다.

additionalItems 옵션을 true로 설정 시 배열 요소가 3개를 초과해도 되며
배열 요소가 3개를 초과할 경우 4번째 요소부터는 타입 검증을 하지 않는다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
{
  "type": "array",
  "items": [
    {
      "type": "integer"
    },
    {
      "type": "string",
      "minLength": 5
    },
    {
      "type": "string",
    }
  ],
  "additionalItems": false
}

배열의 길이가 1 이상 3 이하여야 한다.

1
2
3
4
5
{
  "type": "array",
  "minItems": 1,
  "maxItems": 3
}

배열 내 중복 값을 검증한다.

  • [1, 2, "1"] : 성공 (타입이 다름)
  • [1, 2, 1] : 실패
    1
    2
    3
    4
    
    {
    "type": "array",
    "uniqueItems": true
    }
    

객체 검증

1
2
3
{
  "type": "object"
}

세부 데이터 검증

키워드설명타입
properties배열의 요소 타입 검증object or array
required객체의 필수 속성을 검증array
minProperties객체의 최소 속성 수를 검증int
maxProperties객체의 최대 속성 수를 검증int
pattern객체의 속성 이름을 검증string
dependencies객체 내 속성의 의존성을 검증object

객체의 속성(property)이 유효한지 검사
firstName 속성과 lastName 속성은 string 타입이어야 한다.

1
2
3
4
5
6
7
{
  "type": "object",
  "properties": {
    "firstName": { "type": "string" },
    "lastName": { "type": "string" },
  }
}

객체의 필수 속성을 검사
firstName 속성과 lastName 속성은 string 타입이어야 하며 필수로 존재해야 한다.

1
2
3
4
5
6
7
8
{
  "type": "object",
  "properties": {
    "firstName": { "type": "string" },
    "lastName": { "type": "string" },
  },
  "required" : [ "firstName", "lastName" ]
}

객체의 속성은 최소 1개 이상, 최대 3개 이하여야 한다.

1
2
3
4
5
{
  "type": "object",
  "minProperties": 1,
  "maxProperties": 3
}

객체의 이름은 무조건 숫자로 시작해야 한다.

1
2
3
4
5
6
{
    "type": "object",
    "propertyNames": {
        "pattern": "^[0-9].+"
    }
}

firstName(이름)은 lastName(성) 없이 단독으로 존재할 수 있지만
lastName(성)은 존재할 경우 firstName(이름) 또한 무조건 존재해야 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string"
    },
    "lastName": {
      "type": "string"
    },
  },
  "dependencies": {
    "lastName": ["firstName"]
  }
}

기타 검증

boolean 검증

1
2
3
{
  "type": "boolean"
}

null 검증

1
2
3
{
  "type": "null"
}

enum 검증

string 값으로 무조건 “a”, “b”, “c” 만 올 수 있다.

1
2
3
4
{
  "type": "string",
  "enum": [ "a", "b", "c" ]
}

상수 검증

해당 객체의 lastName 속성은 무조건 “Lee”로만 올 수 있다.

1
2
3
4
5
6
7
{
  "properties": {
    "lastName": {
      "const": "Lee"
    }
  }
}

스키마 결합

명시된 배열에 나열된 모든 JSON 스키마를 한 번에 검증할 수 있다.

키워드설명
allOf배열 내 모든 스키마에 대한 검증을 통과해야 함
anyOf배열 내 하나 이상의 스키마에 대한 검증을 통과해야 함
oneOf배열 내 하나의 스키마에 대한 검증을 통과해야 함

allOfanyOf를 사용한 윤년계산기

  • 4로 나누어 떨어지는 해는 윤년
  • 100으로 나누어 떨어지는 해는 평년
  • 400으로 나누어 떨어지는 해는 윤년
1
2
3
4
5
6
7
8
9
10
11
{
  "allOf": [
    { "type": "number", "multipleOf": 4 },
    {
      "anyOf" : [
        { "multipleOf": 400 },
        { "not" : { "multipleOf": 100 } },
      ]
    }
  ]
}

2 또는 3의 배수이어야 함. 그러나 6의 배수이면 안됨.

1
2
3
4
5
6
{
  "oneOf": [
    { "type": "number", "multipleOf": 2 },
    { "type": "number", "multipleOf": 3 }
  ]
}

스키마 조건

not

스키마 조건에 맞지 않아야 함

1
2
3
  "not": {
    "type": "string"
  }

if-then-else

  • if 만족 => then 실행
  • if 불만족 => else 실행

정수형 키워드일 경우 0 이상의 값만 허용하고
아닐 경우 null만 허용한다.

1
2
3
4
5
6
7
8
9
10
11
{
  "if": {
    "type": "integer"
  },
  "then": {
    "minimum": 0
  },
  "else": {
    "const": null
  }
}

스키마 재사용

$id

  • $id는 JSON 스키마가 대상으로 하는 데이터의 식별자를 정의하는 키워드.
  • $id는 URI 문자열이며 현재 스키마에 고유한 식별자로 사용됨.
  • 이를 통해 스키마가 다른 스키마에서 참조될 때, 해당 스키마가 어디에서 왔는지 파악할 수 있음.
  • 보통 최상위에 스키마 다운로드 위치를 선언함.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/user.schema.json",
  "title": "User",
  "type": "object",
  "properties": {
    // ...
  }
}

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "http://example.com/address.schema.json",
  "title": "Address",
  "type": "object",
  "properties": {
    // ...
  }
}

$ref

$ref 를 사용해서 스키마를 재사용할 수 있다. 예제로 $ref를 사용하는 방법을 확인하는 게 더 빠를 것 같아 바로 예제를 준비했다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
  "type": "object",
  "properties": {
    "firstName": {
      "type": "string",
    },
    "lastName": {
      "$ref": "#/lastName"
    },
    "email": {
      "$ref": "#/components/email"
    },
    "address": {
      "$ref": "#/components/address"
    }
  },
  "components": {
    "email": {
      "type": "string",
      "minLength": 5,
    },
    "address": {
      "type": "string",
      "maxLength": 10,
    }
  },
  "lastName": {
    "pattern": "^Lee$"
  }
}

위 json처럼 # 키워드를 사용해 현재 json 파일의 다른 설정값을 참조할 수도 있고,
특정 URL을 기입하여 외부의 json scheme를 가져와 적용할 수도 있다.

This post is licensed under CC BY 4.0 by the author.