Skip to main content

Command Palette

Search for a command to run...

GraphQL vs REST API

Updated
3 min read

GraphQL은 API를 위한 Query Language이다.

우리에게 더 익숙한 REST API와 GraphQL의 차이점이 무엇인지 알아보고, Next.js에서 GraphQL을 사용하는 방법에 대해 알아보겠다.

REST API

Representational State Transfer의 약자로 URL로 자원을 표현하고 HTTP 요청을 통해 CRUD를 실행하는 API이다.

GET api/todos/1
PUT api/todos/1

처럼 HTTP 메소드와 URL을 조합해서 여러 요청을 할 수 있다.

하지만 REST API에는 2가지 단점이 있다.

Over Fetching

API 호출 시 필요 이상의 데이터를 가져오는 것이다. API를 요청하면 좋든 싫든 주는 대로 받아야 한다. 따라서, 자신이 클라이언트에 보여줄 것 이상으로 데이터를 많이 받기 마련이다.

Under Fetching

한 번의 API 호출로 원하는 모든 데이터를 가져오지 못하는 것이다. 즉 필요한 모든 데이터를 가져오기 위해서 2번, 3번 이상의 API 호출을 해야 하는 경우이다.

예시로 스터디 목록과 멘토 목록을 API로 불러오게 될 경우
GET api/study, GET api/study/mentor
이런 식으로 구분해서 2번의 API 요청을 보내야 한다.

API 요청 수가 많아지면 로딩 속도가 저하되기 때문에 비경제적이다.

GraphQL

GraphQL은 위의 Over Fetching과 Under Fetching을 해결하기 위해 등장한 specification이다. GraphQL은 하나의 endpoint에 자신이 원하는 만큼만 데이터를 요청하고 받기 때문에 overfetching, underfetching이 없다.

그러면 REST 안 쓰고 다들 GraphQL 쓸텐데 왜 그렇지 만은 않을까?

GraphQL도 단점이 있다.

  1. HTTP 캐싱을 활용하기 어렵다
    REST의 경우 endpoint 별로 캐싱을 지정할 수 있는 반면
    GraphQL은 단일 endpoint 이기 때문에 활용하기 어렵다.

  2. 에러 핸들링이 어렵다
    여러 데이터를 하나의 endpoint에 묶어 요청하니 당연히 어렵다

  3. 요청이 무거워진다
    클라이언트 측에서 보내는 요청의 쿼리가 복잡해지고
    이에 대응하기 위해 백엔드에서는 더욱 정교하게 설계해야 한다.

결론: GraphQL은 경제적이지만 설계와 사용이 복잡해진다.

Next.js에서의 GraphQL

https://beta.pokeapi.co/graphql/console/

위의 링크는 포켓몬 데이터 GraphQL 서버이다.
간단하게 포켓몬의 id, 이름, 기술명을 받아와서 페이지에 뿌려보겠다.

API의 endpoint는 https://beta.pokeapi.co/graphql/v1beta로 하나이고
Explorer에서 원하는 데이터를 선택하고 실행하면 데이터를 확인할 수 있다.

vscode에서 Next 프로젝트를 하나 생성 해준다.

page.tsx에 내용을 싹 날려주고

npm i @apollo/client graphql
import { ApolloClient, InMemoryCache, gql } from "@apollo/client";

const client = new ApolloClient({
  cache: new InMemoryCache(),
  uri: "https://beta.pokeapi.co/graphql/v1beta",
});

interface Pokemon {
  base_experience: number;
  id: number;
  name: string;
  pokemon_v2_pokemonabilities: {
    pokemon_v2_ability: {
      name: string;
    };
  }[];
}

const GET_POKEMONS = gql`
  query GetPokemons($first: Int!) {
    pokemon_v2_pokemon(limit: $first) {
      id
      name
      base_experience
      pokemon_v2_pokemonabilities {
        pokemon_v2_ability {
          name
        }
      }
    }
  }
`;

const getPokemons = async () => {
  const { data } = await client.query({
    query: GET_POKEMONS,
    variables: { first: 10 },
  });
  return data.pokemon_v2_pokemon;
};

export default async function Page() {
  const pokemons = await getPokemons();
  return (
    <div className="grid grid-cols-5 gap-6">
      {pokemons.map((pokemon: Pokemon) => (
        <div key={pokemon.id} className="border border-white w-80 p-6">
          <h2 className="capitalize text-2xl">{pokemon.name}</h2>
          <p>Base Experience: {pokemon.base_experience}</p>
          <p>
            Abilities:{" "}
            {pokemon.pokemon_v2_pokemonabilities
              .map((ability) => ability.pokemon_v2_ability.name)
              .join(" ")}
          </p>
        </div>
      ))}
    </div>
  );
}

위와 같이 작성해주면 'use client' 나 ApolloProvider 등 사용 없이 간편하게 graphql을 가져다 사용할 수 있다.

주의해야 할 점은 interface를 명시해줘야만 객체가 자동 완성 된다.

참고자료

https://graphql.org/
https://yozm.wishket.com/magazine/detail/2113/
https://www.tabnine.com/code/javascript/functions/apollo-client/ApolloClient/query

More from this blog

[ZSH] tree 사용하기

들어가며 큰 규모의 프로젝트를 출시한 뒤, 후일을 위해서 더 늦기 전에 파일 정리 및 문서화를 진행해야했다. 문서화 작업을 하는 중에 기왕 정리하는 거 파일 구조를 이쁘게 트리 구조로 나열하여 코멘트를 달면 나중에 보더라도 이해하기 더 쉬울 것 같았다. 어떻게 해야 간지나는 트리 구조를 만들 수 있을까 방법을 찾다보니 역시나 파일 구조를 트리로 이쁘게 출력해주는 커맨드 툴이 존재했다. tree 커맨드에 대해서 알아보고 알짜배기 내용만 정리했다....

Feb 21, 20242 min read

[Next.js] parallel routes & intercepting routes

트위터 로그인 모달창을 만들어보며 넥스트의 parallel routes 와 intercepting routes 을 학습한 내용을 정리해보았습니다. 트위터 로그인 창을 확인해봅시다. 루트 디렉토리 화면을 배경으로 i/flow/login 페이지가 동시에 표시되고 있습니다. 저는 app router 를 학습하기 전까지는 createPortal 을 사용하여 포탈 영역에 로그인 컴포넌트를 띄우는 방식을 사용했었습니다. const NoLogin =()=...

Feb 1, 20244 min read

C/C++ 이진 트리(binary tree) 개요 및 구현(1)

개요 트리는 노드들이 나무 가지처럼 연결된 비선형 계층적 자료구조이다. 하위 트리가 존재하고, 그 노드에 또 하위 트리가 존재하는 자료구조 이다. 트리의 맨 위에 있는 루트 노드가 존재한다. 우리가 알아볼 트리는 이진 트리이다. 이진 트리는 자식 노드(부모로부터 아래로 이어진 노드)가 2개 이하인 구조를 말한다. 트리의 사용 사례로는 다음과 같다 계층 적 데이터 저장(파일,폴더) 효율적인 검색 속도 힙 데이터 베이스의 인덱싱 트리에 ...

Jan 31, 20244 min read

[React] Server component (RSC)

React.js 18 에 도입된 리액트 서버 컴포넌트는 서버에서 동작하는 리액트 컴포넌트를 의미합니다. Next가 권장하는 라우팅 방식인 app router의 기반이 되는 컴포넌트이기 때문에 app router 를 이해하기 위해서는 server component 에 대한 이해가 필요합니다. server component 리액트는 클라이언트단만을 컴포넌트화하는 대신, server component라는 개념을 통해 서버 영역을 컴포넌트화합니다. ...

Jan 29, 20243 min read

Flutter, JavaScript

42 posts