손쉬운 JSON 클래스 되살리기

JSON.parse()는 일부 JSON 텍스트를 일반 Javascript 객체 또는 배열로 구문 분석하는 데 사용하는 표준 Javascript 함수입니다.

그러나 얻을 수 있는 것은 일반 개체, 배열, 문자열, 숫자, 부울 또는 null 값의 혼합일 뿐입니다. 데이터 소스가 클래스의 인스턴스로 만들어졌거나 날짜 개체로 만들어진 경우 작업이 완료된 것입니다. 효율적으로 복구할 수 없습니다.

그러나 JSON.parse() 발견된 각 키-값 쌍에 대해 구문 분석 중에 호출되는 소생 기능을 두 번째 인수로 수락하지만 컨텍스트에 관계없이 키 이름만 가지고 있습니다. 개체의 계층 구조에 있는 위치는 어디입니까? 배열의 경우 더 나쁩니다. 키가 "0"이면 구조의 배열이 많으면 어떤 배열에 대해 이야기하고 있습니까? 정말, 당신은 끝났습니다 ...

우리에게 필요한 것은 대상 데이터 구조의 계층을 처리하는 리바이버를 설계하는 것입니다. 우리는 사용이 간편하기를 원합니다. 이것은 JSON 데이터를 일반 개체, 배열 및 클래스 인스턴스의 임의 계층 구조로 되살리는 데 도움이 되는 Typescript 라이브러리인 @badcafe/jsonizer 의 작업입니다.

예를 들어 시작하겠습니다.

{
    "name": "Bob",
    "birthDate": "1998-10-21T00:00:00.000Z",
    "hobbies": [
        {
            "hobby": "programming",
            "startDate": "2021-01-01T00:00:00.000Z"
        },
        {
            "hobby": "cooking",
            "startDate": "2020-12-31T00:00:00.000Z"
        }
    ]
}


이것은 문자열화된 Date 인스턴스를 포함하는 일반적인 JSON 파일입니다. JSON.parse()는... 문자열만 제공합니다. 그러나 Jsonizer를 사용하면 날짜 인스턴스를 되살리기 위해 예상되는 매핑을 표현할 수 있습니다.

const personReviver = Jsonizer.reviver({
    birthDate: Date,
    hobbies: {
        '*': {
            startDate: Date
        }
    }
});
// personJson contains the JSON string displayed previously
const personFromJson = JSON.parse(personJson, personReviver);


Jsonizer의 reviver 함수는 변환해야 하는 필드에 대한 매핑을 포함하는 일반 객체를 인수로 취한다는 것을 이해하기 쉽습니다(유형 데이터에 대해 '증가'라고 말해야 함). '*' 배열 내부의 모든 배열 항목hobbies과 일치하는 항목도 있습니다! ('*' 낯익지 않나요?)

이것이 Jsonizer가 빛나는 곳입니다. 단일 매핑을 컨텍스트로 만드는 계층을 처리할 수 있으며 매퍼는 표현하기가 정말 쉽습니다.

계속하자. 취미가 수업이라고 합시다. Jsonizer가 리바이버를 정의하는 방법은 무엇입니까? 클래스의 경우 데코레이터@Reviver를 사용합니다.

@Reviver<Hobby>({ // 👈  bind the reviver to the class
    '.': ({hobby, startDate}) => new Hobby(hobby, startDate),
    // 👆 instance builder
    startDate: Date
})
class Hobby {
    constructor(
        public hobby: string,
        public startDate: Date
    ) {}
}


  • Typescript로 전환했지만 예제는 Javascript에서도 작동합니다. 코드에서 유형 정보를 제거하고 생성자에서 필드 할당을 작성하기만 하면 됩니다... 아니면 Typescript로 이동할 때라고 생각하십시오!
  • 데코레이터 기능@Reviver을 사용하여 다시 한 번 매퍼로 클래스를 장식할 수 있지만 이 매퍼에는 '.' 인스턴스를 생성하는 방법을 나타내는 (익숙해 보이는) "self"항목이 특수 항목Hobby이 있습니다.
  • 오! Typescript 사용의 또 다른 장점은 매퍼가 소스 데이터 구조에 있는 필드로 제한되어 올바른 매핑을 쉽게 정의하는 데 도움이 된다는 것입니다.

  • 이제 첫 번째 매핑에서 참조할 수 있습니다.

    const personReviver = Jsonizer.reviver({
        birthDate: Date,
        hobbies: {
            '*': Hobby // 👈  we can refer a class
                       //     decorated with @Reviver
        }
    });
    


    구문 분석 후 hobbies에는 Hobby 인스턴스의 배열이 포함됩니다!

    좋아요... 하지만 Date는 어떻습니까? 글쎄, Jsonizer가 리바이버를 배송하는 것은 매우 일반적입니다. 그래서 당신은 그것을 사용할 수 있습니다.

    마지막으로 Person 클래스를 정의하고 리바이버에 바인딩할 수도 있습니다.

    @Reviver<Person>({
        '.': ({name, birthDate, hobbies}) => new Person(name, birthDate, hobbies), 
        birthDate: Date,
        hobbies: {
            '*': Hobby
        }
    })
    class Person {
        constructor(
            public name: string,
            public birthDate: Date,
            public hobbies: Hobby[]
        ) {}
    }
    


    그것을 사용하는 것도 간단합니다.

    const personReviver = Reviver.get(Person); // 👈  extract the reviver from the class
    const personFromJson = JSON.parse(personJson, personReviver);
    // this is 👆 an instance of Person
    


    읽어 주셔서 감사합니다 ! @badcafe/jsonizer 을 살펴보도록 초대합니다. 더 뛰어난 기능을 찾을 수 있습니다!

    좋은 웹페이지 즐겨찾기