본 포스트에서는 Front-end는 리액트, Back-end는 Express 기반의 Node.js를 사용하여 하나의 프로젝트로 간단한 Application을 구성해 보겠습니다. 구성할 Application은 이전 포스트에서 진행했던 네이버 API 조회 Application을 재사용 하겠습니다.

 

 

React + Express + TypeScript 프로젝트 구성하기

 

이전 포스트에서는 TypeScript 컴파일 환경 및 프로젝트 실행 환경을 구성하고 컴파일한 ./dist/app.js 프로그램으로 Node.js 서버를 구동하는 부분까지 작업해 보았습니다. 이번 포스트에서는 Controller와 Serivce를 생성해서 브라우저에서 받은 요청을 Naver API로 전달하여 응답을 받은 후, 사용자의 브라우저로 전달하는 부분을 작성해 보겠습니다.

 

데이터 타입 선언

먼저 각 데이터의 타입을 선언해 보겠습니다. 데이터의 타입은 interface로 선언하며 ./src/interface/ 하위에 apidata.interface.ts 파일을 생성하여 작성합니다. 이전 포스트에서 사용했던 Naver API의 데이터 종류는 아래와 같습니다.

 

인터페이스 응답

Naver API의 전체적인 응답 Layout은 아래와 같습니다.

{
    lastBuildDate: '',
    total: 0,
    start: 0,
    display: 0,
    items: []
}

 

뉴스 API 데이터

뉴스 API 요청에 대한 응답 Layout은 아래와 같습니다.

{
    title: '',
    originallink: '',
    link: '',
    description: '',
    pubDate: ''
}

 

도서 API 데이터

도서 API 요청에 대한 응답 Layout은 아래와 같습니다.

{
    title: '',
    link: '',
    image: '',
    author: '',
    price: '',
    discount: '',
    publisher: '',
    pubdate: '',
    isbn: '',
    description: ''
}

 

위에서 확인한 데이터를 interface로 ./src/interface/apidata.interface.ts 프로그램에 아래와 같이 선언합니다.

interface INaverApiResp {
    lastBuildDate: string;
    total: number;
    start: number;
    display: number;
    type: string;
    items: INewsData[] | IBookData[];
}

interface INewsData {
    title: string;
    originallink: string;
    link: string;
    description: string;
    pubDate: string;
}

interface IBookData {
    title: string;
    link: string;
    image: string;
    author: string;
    price: string;
    discount: string;
    publisher: string;
    pubdate: string;
    isbn: string;
    description: string;
}

export {
    INaverApiResp,
    INewsData,
    IBookData
}

 

해당 Layout은 Service class에서 참조해야 하므로 export하여 다른 class에서 참조할 수 있도록 합니다. Naver API 데이터에 대한 부분은 아래 포스트에서 예제를 확인할 수 있습니다.

React 기초 (목록 만들기) 05 - ListView UI 구성 :: 즐거운인생 (tistory.com)

 

React 기초 (목록 만들기) 05 - ListView UI 구성

본 포스트에서는 리액트를 이용하여 네이버 API로 데이터를 검색해서 목록 화면을 구성해 보겠습니다. 저번 포스트에서 Naver News API를 호출해서 아래 형태로 결과를 받아보는 부분까지 진행해 보

redballs.tistory.com

 

Class 선언

추가로 두 가지 유형을 더 선언해 보겠습니다.  현재 작성하는 것은 서버 프로그램이므로 클라이언트의 HTTP 요청에 응답할 표준 Layout이 필요합니다. 간단하게 응답코드, 메시지, 데이터 본문으로만 구성해서 Class를 생성해 보겠습니다. 실제 사용 시에는 new 키워드로 인스턴스를 생성하여 사용하겠습니다.

 

interface와의 차이점은 interface는 Naver API에서 받아온 데이터의 응답에 대한 유형을 선언하고 타입 확인만 필요한 형태에 사용하지만 직접 데이터를 생성하는 부분은 class를 선언하고 인스턴스를 생성해서 사용합니다.

 

./src/entity/httpresp.entity.ts 파일을 생성하고 먼저 HTTP 요청에 대한 응답 Layout으로 사용할 HttpResp class를 아래와 같이 생성합니다.

class HttpResp {
    private code: string;
    private message: string;
    private data: RespData | null = null;

    constructor (code: string = '00', message: string = 'Success') {
        this.code = code;
        this.message = message;
    }

    public setCode = (code: string): void => {
        this.code = code;
    }

    public setMessage = (message: string): void => {
        this.message = message;
    }

    public setData = (data: RespData | null): void => {
        this.data = data;
    }
}

 

속성은 3개를 정의했습니다. 응답코드(code), 응답메시지(message), 응답데이터(data) 크게 3가지 정보를 사용하여 응답합니다. constructor는 new 키워드로 인스턴스를 생성할 때 사용하는 생성자입니다. code와 message를 파라미터로 받으며  입력하지 않을 경우 '00', 'Success'로 각각 세팅합니다.

 

응답데이터인 data는 RespData라는 타입으로 선언합니다. RespData라는 타입은 아직 생성하지 않았으니 아직은 오류가 발생합니다. 그리고 응답데이터는 초기에는 값이 없으므로 null도 허용해 주고, 초기값은 null로 세팅합니다. 아래와 같이 | (pipeline)으로 연결하면 여러 유형을 허용할 수 있습니다.

const data: RespData | null = null;

 

그리고 class에서 사용하는 속성들에 대해서는 setter만 선언 했습니다. 나중에 getter가 필요하게 되면 추가적으로 선언해도 되고, 서버에서 데이터를 수신 받아 응답만 할 목적이므로 아직까지는 getter는 필요가 없어 보입니다.

 

그럼 다음으로 응답데이터에 사용하는 RespData class를 아래와 같이 작성합니다. 별도의 파일로 생성하지 않고 동일한 파일에 작성합니다.

class RespData {
    private total: number = 0;
    private start: number = 0;
    private display: number = 0;
    private type: string = '';
    private items: INewsData[] | IBookData[] | null = null;

    constructor (type: string) {
        this.type = type;
    }

    public setTotal = (total: number): void => {
        this.total = total;
    }

    public setStart = (start: number): void => {
        this.start = start;
    }

    public setDisplay = (display: number): void => {
        this.display = display;
    }

    public setType = (type: string): void => {
        this.type = type;
    }

    public setItems = (items: INewsData[] | IBookData[]): void => {
        this.items = items;
    }
}

 

Naver API에서 넘겨주는 total (전체건수), start (시작 인덱스), display (표시 건수)는 숫자 형태로, 초기값을 0으로 선언합니다. 그리고 items는 Naver API에서 넘겨주는 뉴스나 도서 목록 데이터입니다. INewsData, IBookData의 배열이나 초기값을 위해 null 타입을 허용합니다.

 

그리고 type이라는 속성을 string 타입으로 생성합니다. 현재 조회한 목록이 뉴스 데이터인지, 목록 데이터인지를 구분하기 위한 값입니다. RespData class 역시 HttpResp와 동일한 사유로 getter는 작성하지 않았습니다. 다음 포스트 등에서 필요하게 되면 추가하겠습니다.

 

이제 필요한 데이터 타입은 모두 작성해 보았습니다. 다음 포스트에서는 실제 사용자의 요청을 받는 역할을 하는 Controller와 Naver API와 인터페이스를 수행하고 데이터를 만드는 Service를 작성하여 인터페이스를 진행해 보겠습니다.

 

300x250

+ Recent posts