본문으로 건너뛰기

JSON Schema 기반 JSON 인텔리센스_VSCode 플러그인 개발 노트 6

무료2020-05-17#Tool#JSON to JSON Schema#json2schema#VSCode JSON字段提示#VSCode JSON字段校验#VSCode jsonValidation

JSON 필드 제안과 검증은 어떻게 이루어질까요? 확장이 가능할까요?

1. JSON 인텔리센스(IntelliSense)

VS Code는 JSON에 대한 제안과 검증 기능을 제공합니다:

길고 복잡한 설정 파일을 편집할 때 특히 유용하며, package.json, tsconfig.json 등 흔히 쓰이는 JSON 설정을 기본적으로 지원합니다.

커스텀 특수 JSON 프로토콜의 경우, JSON Schema를 통해 확장 지원이 필요합니다.

2. JSON Schema

JSON에 대한 인텔리센스(또는 검증)를 수행하려면, 먼저 JSON의 구조, 필드 값, 의미 등 메타 정보를 명확히 정의한 메타데이터가 필요합니다.

VS Code에서 이 메타데이터는 JSON Schema로 기술됩니다:

To understand the structure of JSON files, we use JSON schemas. JSON schemas describe the shape of the JSON file, as well as value sets, default values, and descriptions.

P.S. VS Code는 현재(2020/05/16) 최신 사양인 JSON Schema Draft 7 규격을 지원합니다.

JSON Schema 역시 JSON 기반의 데이터 형식으로, JSON 데이터의 구조를 정의하는 데 사용됩니다:

JSON Schema specifies a JSON-based format to define the structure of JSON data for validation, documentation, and interaction control.

(출처: JSON Schema)

예를 들어 person.json:

{
  "first_name": "George",
  "last_name": "Washington",
  "birthday": "1732-02-22",
  "address": {
    "street_address": "3200 Mount Vernon Memorial Highway",
    "city": "Mount Vernon",
    "state": "Virginia",
    "country": "United States"
  }
}

이에 대응하는 JSON Schema는 다음과 같습니다(person.schema.json):

{
  "type": "object",
  "properties": {
    "first_name": { "type": "string" },
    "last_name": { "type": "string" },
    "birthday": { "type": "string", "format": "date" },
    "address": {
      "type": "object",
      "properties": {
        "street_address": { "type": "string" },
        "city": { "type": "string" },
        "state": { "type": "string" },
        "country": { "type" : "string" }
      }
    }
  }
}

위 예시는 JSON의 타입 선언처럼 보이지만, 실제로는 타입 외에도 필드 값이나 의미 설명 등의 정보를 포함할 수 있습니다:

{
  "type": "string",
  "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$",
  "title": "telephone number",
  "description": "a simple North American telephone number with an optional area code"
}

P.S. JSON Schema에 대한 자세한 정보는 Understanding JSON Schema를 참고하세요.

3. 커스텀 JSON 제안 확장

VS Code가 제공하는 JSON 제안 기능이 JSON Schema 기반이므로, 커스텀 JSON 형식을 지원하는 것은 상당히 쉽습니다:

  1. 먼저 제안/검증에 필요한 메타데이터를 갖춘 JSON Schema를 생성(수동 작성 또는 변환 생성)합니다.

  2. 대상 JSON 파일과 연결을 설정하여, VS Code가 특정 JSON 파일을 열 때 해당 제안 정보(JSON Schema)를 찾을 수 있도록 합니다.

JSON Schema 생성

간단하고 업데이트가 잦지 않은 JSON 데이터는 직접 JSON Schema를 작성하면 되지만, 복잡하고 길며 필드가 수시로 추가되는 데이터는 도구를 통해 변환 생성하는 것이 더 나은 선택일 수 있습니다:

  • JSON을 JSON Schema로 변환: JSON Schema Tool(비공개 소스이나 변환 및 편집 통합, Draft-07 지원) 또는 to-json-schema(오픈 소스, 변환 전용, 다른 편집기와 함께 사용)를 추천합니다.

  • JSON Schema 편집: JSON-Schema-Editor 시각화 편집기를 추천합니다.

  • JSON Schema 구문 검증: JSON Schema Validator

JSON Schema가 올바르게 생성되었다면, VS Code에서 JSON 파일과 연결만 해주면 됩니다.

JSON 파일과 연결 설정

JSON Schema와 JSON 파일을 연결하는 방법은 세 가지가 있습니다:

  • 사용자 측: 사용자 설정(Settings)의 json.schemas 옵션을 통해 매핑 관계를 구성합니다.

  • 데이터 측: JSON 데이터에 JSON Schema를 가리키는 $schema 필드를 추가합니다.

  • 제3자(플러그인): jsonValidation 기여 포인트(Contribution Point)를 통해 매핑 관계를 구성합니다.

json.schemas

"json.schemas": [
  {
    "fileMatch": [
      "/.babelrc"
    ],
    "url": "http://json.schemastore.org/babelrc"
  }
]

P.S. JSON Schema Store는 200개 이상의 흔한 설정 파일에 대한 JSON Schema를 제공합니다.

이름이 .babelrc인 모든 JSON 파일에 url이 가리키는 JSON Schema를 적용한다는 의미입니다. 여기서 url은 로컬 파일의 상대 경로일 수도 있습니다. 예: "url": "./myschema.json"은 현재 워크스페이스 루트의 myschema.json을 의미합니다.

또는 JSON Schema를 직접 작성할 수도 있습니다:

"json.schemas": [
  {
    "fileMatch": [
      "/.myconfig"
    ],
    "schema": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of the entry"
        }
      }
    }
  }
]

사용자 설정은 조작이 간편하고 JSON 데이터에 영향을 주지 않지만, 로컬 설정이라 공유되지 않아 협업 시 모든 사용자가 설정해야 한다는 단점이 있습니다. 또한 fileMatch 규칙으로 매핑을 묘사하기 어려운 특수 상황이 있을 수 있는데, 이때는 $schema를 고려할 수 있습니다.

P.S. 주의: JSON 데이터 파일 확장자가 .json이 아닌 경우, files.associations를 설정하여 해당 파일을 JSON으로 처리하도록 명시해야 합니다(JSON Schema 설정은 JSON 파일에만 적용되기 때문입니다):

"files.associations": {
  ".babelrc": "json"
}

자세한 내용은 Adding a file extension to a language를 참고하세요.

$schema

{
  "$schema": "http://json.schemastore.org/coffeelint",
  "line_endings": "unix"
}

JSON 데이터 내의 특수한 $schema 필드를 통해 대응하는 JSON Schema를 포함하는 방식입니다. 단점은 JSON 데이터를 오염시키며, 모든 소비자가 $schema에 대한 예외 처리를 해야 한다는 것입니다. 또한 제3자가 제공하는 데이터처럼 데이터 측을 제어할 수 없는 경우에는 필드 추가가 거의 불가능하므로 적합하지 않습니다.

장점은 일대일의 정밀한 매핑이 가능하다는 것입니다. fileMatch 규칙으로는 설명하기 어려운 상황(예: 커스텀 JSON 파일명이 package.json과 겹치거나 파일명이 고정되지 않은 경우)을 충족할 수 있습니다. (자세한 내용은 support setting schema associations at runtime을 참고하세요. 향후 데이터에 침입하지 않으면서도 더 유연한 JSON Schema 연결 방식이 제공될 수 있습니다.)

jsonValidation

{
  "contributes": {
    "jsonValidation": [
      {
        "fileMatch": ".jshintrc",
        "url": "http://json.schemastore.org/jshintrc"
      }
    ]
  }
}

json.schemas 사용자 설정과 유사하지만, 매핑 관계를 플러그인의 package.json에 모아서 제공함으로써 설정 공유 문제를 해결합니다. 다만 매핑 관계 묘사 능력의 한계는 여전히 존재합니다.

P.S. jsonValidationurl 형식을 통한 JSON Schema 로드만 지원하며, schema 필드를 통해 직접 작성하는 방식은 지원하지 않습니다.

4. 자동 완성

JSON Schema 사양의 default 필드는 JSON 자동 완성에 사용될 수 있으며(VS Code 기본 지원), 일반적인 상황을 충족합니다. 더 복잡한 완성 제안의 경우, 확장 필드인 defaultSnippets를 사용할 수 있습니다:

{
  "type": "array",
  "title": "Keybindings configuration",
  "items": {
    "type": "object",
    "required": ["key"],
    "defaultSnippets": [
      {
        "label": "New keybinding",
        "description": "Binds a key to a command for a given state",
        "body": { "key": "$1", "command": "$2", "when": "$3" }
      }
    ],
    "properties": {
      "key": {
        "type": "string"
      }
    }
  }
}

defaultSnippets 내의 body 구문은 Snippets과 동일하며, 커서 위치 제어, 자리 표시자(placeholder), 미리 정의된 상수(현재 파일명, 날짜 등) 사용을 지원합니다.

P.S. defaultSnippets는 JSON Schema 표준의 일부가 아니라, VS Code가 JSON 완성 능력을 강화하기 위해 확장한 커스텀 필드입니다. (JSON Schema 사양은 확장을 허용하며 알 수 없는 모든 필드는 무시됩니다.)

참고 자료

댓글

아직 댓글이 없습니다

댓글 작성