본문 바로가기

main/GraphQL

React-Native (TypeScript) 에서 GraphQL 사용하기 - 1

⭐ GraphQL이란

REST API 대신 사용할 수 있는 웹서비스 아키텍쳐.

 

REST API는 서버에서 보내주는 명세대로 클라이언트에서 사용하고, 필요한 데이터나 구조의 변경이 필요하면 요청하는 방식으로 사용한다.

 

GraphQL은 클라이언트가 필요한 데이터의 구조를 직접 지정하고 서버는 이를 반환한다.

불필요한 데이터를 받게 되거나, 필요한 데이터를 받지 못하는 문제를 피할 수 있는 것이 장점이다.

 

각각의 장단점이 있을 것이다. 지금껏 거의 REST API를 사용해왔지만 현재 진행하고 있는 사이드 프로젝트에서 GraphQL을 사용하고 있어서 나도 직접 써볼 수 있었다.

 

import {gql, useQuery} from '@apollo/client';

namespace PlacesQuery {
  export interface Param {
    Dto: {
      keyword: string;
      x: number;
      y: number;
    };
  }
  export interface Response {
    getNearSpots: {
      spots : Array<{
        _id: string;
        address_name: string;
        category_name: string;
        x: number;
        y: number;
      }>;
    };
  }
}

변수명은 임의로 변경했음... 실제로 저렇게 막 쓰지는 않는다 😅

namespace에 Query 타입들을 지정해 준다.

 

const NEAR_QUERY = gql`
  query {
    getNearSpots(
      searchSpotDto: {
        keyword: "",
        x: 127.0473,
        y: 37.5172,
      }
    ) { 
      spots {
        _id
        address_name
        category_name
        x
        y
      }
    }
  }
`;

실제 서버에 보낼 쿼리문을 작성한다.

위쪽의 Dto 에는 실제 실어 보낼 값들을 넣어주고, 아래쪽의 sp에서는 응답받을 타입들만 입력해주면 된다.

 

export default function usePlacesQuery(param: PlacesQuery.Param): PlaceDTO[] {
  let places: PlaceDTO[] = [];
  const {loading, error, data} = useQuery<
    PlacesQuery.Response,
    PlacesQuery.Param
  >(NEAR_SPOTS_QUERY, {
    variables: param,
  });

  if (data && data.getNearSpots) {
    places = data.getNearSpots.spots.map(spot => ({
      id: `p_${spot._id}`,
      placeName: spot.place_name,
      position: [spot.x, spot.y],
    }));
  }

  console.log('places: ', places);

  return places;
}

PlaceDTO는 미리 정의해둔 타입 interface이다. 필요한 데이터만 place로 받는다.

 

그럼 쿼리문을 보낼 때 이 스키마들은 어떻게 알 수 있냐?

서버분들에게 받은 Docs에 잘 나와있었다.. 이건 아마 서버분들이 잘 정리해주신 게 아닐까!

클라이언트 개발 하면서 서버랑 커뮤니케이션 할 때, 이렇게 명세에서부터 설명이 꼼꼼하고 잘 정리돼있으면 개발하기 편하다고 항상 느꼈던 것 같다.

 

근데 사실 graphQL 아직 맛보기 단계라 이것저것 사용해 보며 좀 더 정리해 봐야겠다.