TypeBox를 사용한 노드 TypeScript JSON 스키마 유효성 검사

소개



오늘 기사에서는 JSON 스키마를 정의하고 TypeScript를 사용하는 노드 환경에서 TypeBox 라이브러리를 사용하여 데이터 유효성 검사를 수행하는 방법을 설명합니다.

JSON 스키마에 대한 데이터 유형을 이미 생성하는 라이브러리가 있지만 인터페이스 및 열거형 세트를 만든 다음 이를 JSON 스키마로 변환하는 데 어려움을 겪은 사람이라면 누구나 이 변환을 수행하는 것이 얼마나 어려운지 알고 있습니다.

그리고 때때로 우리는 우리 자신의 제네릭을 만들어야 하거나 라이브러리가 우리에게 제공하는 것에 문자 그대로 제한되어 있습니다. 결국 실제 문제를 실제로 해결하는 것보다 데이터 유형과 관련된 문제를 해결하는 데 더 많은 시간을 소비하게 되는 경우가 많습니다.

이와 같은 이유로 TypeScript 지원이 일급 시민이라고 생각하기 때문에 TypeBox를 사용하는 것을 좋아합니다.

시작하기



이미 가지고 있는 TypeScript가 있는 노드 환경에서 다음 종속 항목을 설치합니다.

npm install @sinclair/typebox --save


오늘 기사의 예에서는 다음과 같이 필요한 세 가지 속성만 있는 스키마를 생성해 보겠습니다.

import { Type, Static } from "@sinclair/typebox";

export const profileSchema = Type.Object({
  firstName: Type.String(),
  lastName: Type.String(),
  age: Type.Integer(),
});


위에서 만든 스키마는 다음 JSON 스키마와 동일합니다.

{
   "type":"object",
   "properties":{
      "firstName":{
         "type":"string"
      },
      "lastName":{
         "type":"string"
      },
      "age":{
         "type":"integer"
      }
   },
   "required":[
      "firstName",
      "lastName",
      "age"
   ]
}


이제 생성된 스키마에서 정적 데이터 유형을 생성해 보겠습니다.

import { Type, Static } from "@sinclair/typebox";

export const profileSchema = Type.Object({
  firstName: Type.String(),
  lastName: Type.String(),
  age: Type.Integer(),
});

// 👇 added this line
export type ProfileSchemaType = Static<typeof profileSchema>; 


그런 다음 스키마를 유일한 인수로 수신하고 반환으로 인수 및 유효성 검사 함수에 전달된 스키마의 "복사본"을 갖는 작은 팩터리를 만들 수 있습니다.

이 유효성 검사 함수에서 우리는 유효성을 검사하려는 속성의 데이터를 유일한 인수로 받습니다. 유효한 경우 동일한 데이터를 반환하고 그렇지 않으면 오류를 발생시킵니다. 이 방법:

import { TObject } from "@sinclair/typebox";
import { TypeCompiler } from "@sinclair/typebox/compiler";

interface ValidatorFactoryReturn<T> {
  schema: TObject;
  verify: (data: T) => T;
}

export const validatorFactory = <T extends unknown>(
  schema: TObject
): ValidatorFactoryReturn<T> => {
  const C = TypeCompiler.Compile(schema);

  const verify = (data: T): T => {
    const isValid = C.Check(data);
    if (isValid) {
      return data;
    }
    throw new Error(
      JSON.stringify(
        [...C.Errors(data)].map(({ path, message }) => ({ path, message }))
      )
    );
  };

  return { schema, verify };
};


마지막으로 인수에서 생성한 스키마를 전달하는 팩터리를 인스턴스화한 다음 .verify() 함수를 사용하여 원하는 데이터의 유효성을 검사할 수 있습니다.

보다 명확한 예를 들어 http 요청 본문에서 데이터의 유효성을 검사하려는 경우 다음과 같이 사용할 수 있습니다.

import Koa from "koa";
import Router from "@koa/router";
import koaBody from "koa-body";

import { profileSchema, ProfileSchemaType } from "./schema";
import { validatorFactory } from "./validator";

const profileValidation = validatorFactory<ProfileSchemaType>(profileSchema);

const app = new Koa();
const router = new Router();

app.use(koaBody());

router.post("/", (ctx) => {
  const body = ctx.request.body as ProfileSchemaType;
  const data = profileValidation.verify(body);
  ctx.body = { data };
});

app.use(router.routes());

app.listen(3000);


그리고 http 요청 본문에서 다음 개체를 보낼 수 있습니다.

{
  "firstName": "Francisco",
  "lastName": "Mendes",
  "job": "Full Stack Dev"
}


예상할 수 있듯이 스키마에 500 속성이 정의되어 있지 않고 job 속성이 없기 때문에 age 오류가 발생할 가능성이 높습니다. 그러나 올바른 개체가 전송되면 응답은 전송된 개체와 동일할 것으로 예상됩니다.

결론



늘 그렇듯이 기사가 마음에 드셨기를 바라며 기존 프로젝트에 도움이 되었거나 단순히 사용해 보고 싶으셨기를 바랍니다.

기사에서 잘못된 부분을 발견했다면 댓글로 알려주시면 수정하겠습니다. 마치기 전에 이 기사의 소스 코드에 액세스하려면 github 저장소에 대한 링크here를 남겨둡니다.

좋은 웹페이지 즐겨찾기