도서/기술

[책] 데이터 지향 프로그래밍 - 12장 고급 데이터 유효성 확인

egg528 2025. 2. 1. 21:36

 최근 Ruby, Python으로 개발을 하며 어려웠던 점 중 하나는 메서드로 들어오고 나가는 데이터의 양식을 명확하게 파악하기 어렵다는 점이다. 물론 두 값에 대한 타입을 따로 정의하지 않아도 되기 때문에 편리한 점은 있지만 규모가 커지고 내가 개발하지 않은 메서드를 손봐야 할 때면 조금 어려워진다.

 

 때마침 12장에서는 메서드 인자와 반환값에 대한 유효성 확인. 그리고 이를 바탕으로 데이터 모델 도식과 테스트 자동 생성에 대해 다룬다.

 

함수 인자 유효성 확인


  7장 데이터 유효성 확인에서 JSON 스키마를 활용해 외부와의 경계에서 데이터를 검증하는 방법에 대해 이야기 했다. 이번 장에서 조금 다른 점은 데이터를 확인하는 시점이 시스템의 내부이자 메서드의 시작과 끝이라는 점이다.  이전보다 조금 더 나아가 다룬 것이라면 JSON 스키마를 통해 데이터의 타입 뿐만이 아니라 형식 또는 값의 범위까지 지정할 수 있다는 점이다.

 

var isbnSchema = {
    "type": "string",
    "pattern": "^[0-9-]{10,20}$"
};

var libIdSchema = {
    "type": "string",
    "pattern": "^[a-z0-9-]{3,20}$"
};

var authorIdSchema = {
    "type": "string",
    "pattern": "^[a-z-]{2,50}$"
};

var bookItemSchema = {
    "type": "object",
    "additionalProperties": {
        "id": uuidSchema,
        "libId": libIdSchema,
        "purchaseDate": {
            "type": "string",
            "format": "date"
        },
        "isLent": {
            "type": "boolean"
        }
    }
};

 예를 들면 위 JSON 스키마에 정의된 format 또는 pattern처럼 데이터의 형식을 지정할 수 있다. 타입 별로 활용할 수 있는 검증 키워드도 다양한데 키워드들은 아래 사이트에서 확인할 수 있다.

 

Catalog.searchBooksByTitle = function(catalogData, query) {
    if (dev()) {
        if (!ajv.validate(searchBooksArgsSchema, [catalogData, query])) {
            var errors = ajv.errorsText(ajv.errors);
            throw ("searchBooksByTitle called with invalid arguments: " + errors);
        }
    }

    var allBooks = _.get(catalogData, "booksByIsbn");
    var matchingBooks = _.filter(allBooks, function(book) {
        return _.get(book, "title").includes(query);
    });

    var bookInfos = _.map(matchingBooks, function(book) {
        return Catalog.bookInfo(catalogData, book);
    });

    if (dev()) {
        if (!ajv.validate(searchBooksResponseSchema, bookInfos)) {
            var errors = ajv.errorsText(ajv.errors);
            throw ("searchBooksByTitle returned an invalid value: " + errors);
        }
    }

    return bookInfos;
};

 또 한 가지 예상과 달랐던 건 JSON 스키마를 활용한 Validation은 운영 환경을 제외하고만 사용하라는 내용이었다. 위 코드처럼 메서드의 시작과 끝에 인자결과에 대한 로직이 있는데 성능에 문제가 될 수 있다는 이유로 운영 외의 환경에서만 권장했다. 다만, 데이터는 결국 외부에서 들어오게 되는데 운영 환경에서는 시스템 외부의 데이터 검증만 있으면 문제 없을 것 같아 이해가 됐다. 결국 이 코드의 역할은 운영 환경에 나가기 전 테스트, 개발 환경에서 오류를 잡아주는 역할을 수행하게 된다.

 

 

 

JSON 스키마를 활용한 데이터 도식과 단위 테스트 자동 생성


 

 이같이 JSON 스키마를 작성하고 나면 얻을 수 있는 이점이 2가지 있다. 바로 UML 도식을 자동으로 만들 수 있다는 점과 Fake 데이터를 기반으로 자동으로 단위 테스트를 작성할 수 있다는 점이다. 책에서는 malli를 사용해 JSON 스키마로 UML 도식을 만들었다.

 

 또한 json-schema-faker를 활용해 JSON 스키마에 부합하는 더미 데이터를 생성해 자동으로 단위 테스트를 작성할 수 있게 해준다고 말하는데, 사실상 자동이라기 보다는 손 쉽게에 가깝다. 또한 아쉬운 점은 메서드 로직에 대한 테스트라기 보다는 입력 데이터와 결과 데이터의 양식 검증만 수행할 뿐이라 아쉬움이 남았다.

 

 

내 생각


 이번 장에서는 JSON 스키마와 타입을 비교하면 JSON 스키마를 사용할 때 얻을 수 있는 장점들을 나열해줬지만 크게 설득력이 있지는 않았다. 타입이 없는 언어를 사용했을 때 가장 큰 장점 중 하나는 개발의 편의성이라 생각하는데 JSON 스키마를 사용하는 건 이런 장점을 없애는 게 아닐까 싶었다. 

 

 결국 모두 장단점이 있는 것 같다.