CodeGym /행동 /C# SELF /JSON과 JSON Schema 검...

JSON과 JSON Schema 검증

C# SELF
레벨 47 , 레슨 4
사용 가능

1. 소개

자, 이미 객체를 JSON으로(또는 그 반대로) 변환할 수 있겠죠. 그런데 프로그램에 뭔가… 이상한 게 들어오면요? 예를 들어, 다음 같은 JSON을 예상했는데:

{
  "id": 123,
  "name": "Alice",
  "email": "alice@example.com"
}

그런데 받은 건:

{
  "name": 42,
  "id": "not a number"
}

네, C#의 직렬화/역직렬화 도구들은 이런 난장판을 '정직하게' 역직렬화하려 하겠지만, 대개는 런타임 오류, 데이터 손실이나 심지어 비즈니스 중단으로 이어집니다. 데이터를 다른 곳으로 넘기거나 DB에 저장하거나 네트워크로 보내기 전에, 데이터가 유효한지 확인하세요 — 그렇지 않으면 코드가 안전장치 없는 곡예사처럼 됩니다.

그래서 검증이 필요한 거예요: JSON이 규칙 — 값의 타입, 필수 필드, 허용 범위, 구조 등 — 에 맞는지 자동으로 확인하는 과정입니다.

2. JSON을 검증하는 방법들

C#/.NET에서는 주로 세 가지 접근이 있어요:

  • 직접 코드로 검증: 객체를 수동으로 파싱하고 검증을 작성해서 에러 시 예외를 던집니다.
  • 모델에 검증 어트리뷰트 사용: 예를 들어, [Required], [Range], [EmailAddress]System.ComponentModel.DataAnnotations 네임스페이스에서 제공됩니다.
  • JSON Schema로 검증 — 오늘의 주인공이에요!

JSON Schema는 유효한 문서가 어떻게 생겼는지 형식적으로 기술할 수 있는 표준입니다. 스키마 자체도 JSON으로 작성되죠. 어떤 필드가 필요한지, 타입은 무엇인지, 어떤 값이 허용되는지 등을 정의할 수 있어요.

스키마로 다음을 설명할 수 있습니다:

  • 어떤 필드가 존재해야 하는지.
  • 어떤 타입이 예상되는지 (string, array, number, object 등).
  • 어떤 필드가 필수이고 어떤 필드가 선택인지.
  • 값의 범위(예: 나이 0에서 150 사이).
  • 패턴, 길이, 허용값 목록 등.

가장 단순한 스키마 예제

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "type": "object",
  "properties": {
    "id":    { "type": "integer" },
    "name":  { "type": "string" }
  },
  "required": ["id", "name"]
}

3. JSON Schema의 주요 요소

예제를 보면서 주요 키들이 무슨 의미인지 정리해볼게요.

설명 예제
$schema
JSON Schema 표준 버전 링크
"https://json-schema.org/draft/2020-12/schema"
type
값의 타입 (object, array, string, number 등)
"type": "object"
properties
객체의 속성 설명
"properties": { ... }
required
필수 필드의 배열
"required": ["id"]
items
배열 요소의 타입 설명
"items": { ... }
enum
허용 가능한 값들의 목록
"enum": ["A", "B"]
minimum
,
maximum
숫자에 대한 제약
"minimum": 0
minLength
,
maxLength
문자열 길이 제한
"minLength": 3
pattern
문자열에 대한 정규식
"pattern": "^[a-zA-Z]+$"

시각적으로: 사람 배열에 대한 스키마 예제

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id":    { "type": "integer" },
      "name":  { "type": "string", "minLength": 2, "maxLength": 50 },
      "email": { "type": "string", "format": "email" }
    },
    "required": ["id", "name"]
  }
}

4. C#에서 JSON을 스키마에 대해 검증하는 방법

현재(.NET 9 기준) .NET에는 JSON Schema에 대한 표준 지원이 없습니다. 실무에서는 외부 라이브러리를 사용해요: NJsonSchema 또는 Newtonsoft.Json.Schema (Json.NET Schema).

Newtonsoft.Json.Schema (Json.NET Schema) 패키지 설치

프로젝트 폴더에서 터미널에 다음을 입력하세요:

dotnet add package Newtonsoft.Json.Schema

중요: Newtonsoft.Json.Schema는 상용 라이브러리지만 비상업적 용도는 무료입니다. 개인 프로젝트에 잘 어울려요.

JSON을 스키마에 맞게 검증하는 예제

using Newtonsoft.Json.Linq;
using Newtonsoft.Json.Schema;

string schemaJson = @"{
  'type': 'object',
  'properties': {
    'id':    { 'type': 'integer' },
    'name':  { 'type': 'string' },
    'email': { 'type': 'string', 'format': 'email' }
  },
  'required': ['id', 'name']
}";

// 예를 들어, 이런 JSON이 있다고 가정해보자
string json = @"{
  'id': 123,
  'name': 'Alice',
  'email': 'alice@example.com'
}";

// 먼저 스키마를 파싱
JSchema schema = JSchema.Parse(schemaJson);

// JSON 자체를 JToken으로 파싱
JToken jsonObj = JToken.Parse(json);

// JSON이 스키마에 맞는지 검사
bool valid = jsonObj.IsValid(schema, out IList<string> errors);

if (valid)
{
    Console.WriteLine("JSON 유효!");
}
else
{
    Console.WriteLine("JSON 유효하지 않음!");
    foreach (var error in errors)
        Console.WriteLine(error);
}

애플리케이션에서 JSON 검사를 어떻게 사용할까?

보통은: 먼저 검증(IsValid), 그다음 역직렬화(JsonConvert.DeserializeObject<T>), 그리고 비즈니스 로직을 진행합니다. 이렇게 하면 초기에 쓰레기 데이터를 걸러낼 수 있어요.

if (jsonObj.IsValid(schema))
{
    // 괜찮다, 역직렬화해도 됨
    var person = JsonConvert.DeserializeObject<Person>(json);
}
else
{
    // 처리 중단! 데이터가 올바르지 않음.
}

5. JSON Schema의 실제 활용

언제 검증이 필요할까?

  • API로 들어오는 데이터(특히 외부 시스템이나 다양한 클라이언트로부터)를 받을 때.
  • 마이크로서비스나 데이터베이스 간 데이터 마이그레이션 시.
  • 스키마 기반으로 UI 폼을 생성하거나 자동 완성할 때.
  • 면접 질문으로도 자주 나옵니다: "잘못된 JSON이 들어오면 어떻게 할래?" 같은 질문.

흥미로운 팁(호기심 있는 사람들을 위해)

  • 포맷 검사: "format": "email", "date-time".
  • 복합 규칙: anyOf, oneOf, allOf.
  • 중첩된 객체와 배열 검증.
  • 필요에 맞게 스키마 확장하기.

6. 큰 실전 예제

입력 데이터(유저 목록):

[
  { "id": 1, "name": "Alice", "email": "alice@example.com" },
  { "id": 2, "name": "Bob" },
  { "id": "이게 뭐지?", "name": 123, "email": "not-an-email" }
]

스키마:

{
  "type": "array",
  "items": {
    "type": "object",
    "properties": {
      "id":    { "type": "integer" },
      "name":  { "type": "string", "minLength": 2, "maxLength": 50 },
      "email": { "type": "string", "format": "email" }
    },
    "required": ["id", "name"]
  }
}

.NET에서의 검사:

string jsonArray = @"[ ... ]"; // 위 참조
string schemaJson = @"{ ... }"; // 위 참조

JSchema schema = JSchema.Parse(schemaJson);
JToken arrayToken = JToken.Parse(jsonArray);

bool isValid = arrayToken.IsValid(schema, out IList<string> errs);
if (!isValid)
{
    foreach (var error in errs)
        Console.WriteLine(error);
    // 예시 메시지:
    // "String '이게 뭐지?' is not a valid integer."
    // "Integer 123 is not a valid string."
    // "String 'not-an-email' is not a valid email address."
}

7. JSON 스키마 작업 시 흔한 실수들

오류 #1: 스키마와 실제 데이터 불일치. 모델을 변경한 뒤 스키마 업데이트를 잊는 경우가 많습니다. 그러면 검증이 오류를 놓치거나 정상 데이터를 차단할 수 있어요.

오류 #2: 스키마와 모델의 타입 불일치. 예를 들어 모델의 필드 타입이 바뀌었는데(예: id가 문자열로 바뀜) 스키마에는 여전히 integer로 남아 있으면 밸리데이터가 에러를 냅니다.

오류 #3: 비즈니스상 필수 필드 누락. 필드가 required로 표시되지 않았다 하더라도 비즈니스 로직이 그 필드에 의존하면, 누락 시 장애가 발생합니다.

오류 #4: 잘못된 데이터 포맷. email이나 날짜 같은 string 필드는 겉보기엔 문자열이지만 유효하지 않을 수 있습니다. format이나 추가 검증을 사용하세요.

오류 #5: 라이브러리 구현이 표준을 따라가지 못함. 표준은 발전하는데 라이브러리는 항상 따라오지 못합니다. 일부 검사가 없거나 다르게 동작할 수 있어요.

1
설문조사/퀴즈
JSON-데이터 다루기, 레벨 47, 레슨 4
사용 불가능
JSON-데이터 다루기
JSON 문법이랑 구조 기본
코멘트
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION