GraphQL과 Apollo를 왜 쓸까?

람다·2022년 1월 7일
0

GraphQL

목록 보기
1/1
post-thumbnail

GraphQL과 Apollo

손쉽게 백엔드와 데이터베이스, 스토리지를 해결해주는 firebase를 이용하면서 편리함을 얻었지만 편리한 만큼 단점도 보였다.

필요한 정보만 쏙쏙 받아오고 싶은데 전체 데이터를 호출한다는 점 (Over-fetching), 그리고 한 번의 요청으로 모든 데이터를 받아오지 못해 여러 번의 요청을 해야 한다는 점이다.

예를 들어, 인스타그램의 메인 페이지에서 다른 유저의 스토리, 게시글, 친구 추천을 불러올 때 이러한 정보들은 GET /users/{id}/story, GET /users/{id}/posts처럼 여러 번의 요청이 필요하다. 이런 여러 호출이 자원 낭비와 느린 로딩 속도를 발생한다는 점이다. (Under-fetching)

이 불편함을 해결하기 위해 방법을 찾다가 graphQL과 이를 구현 시켜줄 Apollo를 찾게 되었다.

왜 GraphQL을 쓸까?

rest api는 관리해야 할 EndPoint의 증가로 발생하는 문제점이 있다. (특정 기능을 위해 여러 번 API가 호출 된다는 점, 유지보수의 어려움 등..)

GraphQL의 특징

1.EndPoint가 하나라는 점

Rest API는 정보를 얻기 위해 여러 번 네트워크를 호출하거나, 다양한 API를 호출해야 했는데, GraphQL은 단 하나의 EndPoint를 제공하며, 한 번의 요청으로 모든 정보를 가져올 수 있는 엄청난 장점이 있다.

2.Over-fetching, Under-fetching 방지

위에서 적었듯 필요한 정보를 얻기 위해 전체 데이터를 가져오는 것은 속도도 느려질뿐더러 자원을 낭비한다. GraphQL은 고정된 endpoint로 요청을 보내기 때문에 정해진 데이터를 받아올 수 있다.

Apollo는 무엇이길래?

GraphQL은 하나의 명세일 뿐이기에 이를 구현할 방법이 필요한데 그 중 하나가 Apollo다. GraphQL 사용을 도와주는 라이브러리인 것이다.

GraphQL 사용법

Queries and Mutations

Field

GraphQL은 객체에 대한 필드를 요청하는 것이 간편하다. 쿼리와 결과가 동일한 형태인 것을 알 수 있는데 이는 서버에서 클라이언트가 요청하는 필드를 알고 있기 때문이다. 필드는 객체를 참조할 수 있다.

  hero {
    name
    friends {
      name
    }
  }
}

아래의 예는 friends 필드가 배열을 반환한다.

{
  "data": {
    "hero": {
      "name": "R2-D2",
      "friends": [
        {
          "name": "Luke Skywalker"
        },
        {
          "name": "Han Solo"
        },
        {
          "name": "Leia Organa"
        }
      ]
    }
  }
}

Arguments

GraphQL은 필드에 인자를 전달할 수 있다. Rest API는 단일의 인자들만 전달할 수 있지만, GraphQL에서는 모든 필드와 중첩된 객체가 인자를 가질 수 있기에 한 번의 요청으로 처리가 가능하다.

요청

{
  human(id: "1000") {
    name
    height(unit: FOOT)
  }
}

응답

{
  "data": {
    "human": {
      "name": "Luke Skywalker",
      "height": 5.6430448
    }
  }
}

Query

정보를 요청해 데이터를 가져올 때 사용한다. (Get)

query {
  teams {
    id
    manager
    office
    extension_number
    mascot
    cleaning_duty
    project
  }
}

Mutation

GET 요청을 제외한 나머지 요청들을 말한다. 해당 정보를 추가하고 삭제하고 변경할 때 사용한다.

추가

mutation {
  postTeam (input: {
    manager: "John Smith"
    office: "104B"
    extension_number: "#9982"
    mascot: "Dragon"
    cleaning_duty: "Monday"
    project: "Lordaeron"
  }) {
    manager
    office
    extension_number
    mascot
    cleaning_duty
    project
  }
}

수정

mutation {
  editTeam(id: 2, input: {
    manager: "Maruchi Han"
    office: "105A"
    extension_number: "2315"
    mascot: "Direwolf"
    cleaning_duty: "Wednesday"
    project: "Haemosu"
  }) {
    id,
    manager,
    office,
    extension_number,
    mascot,
    cleaning_duty,
    project
  }
}

삭제

mutation {
  deleteTeam(id: 3) {
    id,
    manager,
    office,
    extension_number,
    mascot,
    cleaning_duty,
    project
  }
}

Apollo Client

GraphQL은 하나의 명세일 뿐이기에 이를 구현할 방법이 필요한데 그 중 하나가 Apollo다. 아래는 React에서 Apollo를 사용하는 방법이다.

Apollo Client 설치

npm install @apollo/client graphql

or

yarn add @apollo/client graphql

설치가 끝났다면 ApolloClient 인스턴스를 초기화 한다.

index.js

import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  useQuery,
  gql
} from "@apollo/client";

초기화를 끝냈다면 index.js에서 uri 및 캐시 필드가 있는 구성 개체를 전달한다.

index.js

const client = new ApolloClient({
  uri: 'https://48p1r2roz4.sse.codesandbox.io',
  cache: new InMemoryCache()
});

uri : graphQL의 서버 URL
cache: cache는 InMemoryCache의 인자이며 불필요한 query 요청을 방지해준다.

Apollo Client 와 React의 연결
위의 과정을 거쳐 ApolloProvider를 앱을 감싸 react에서 활용할 수 있게 연결한다.

import React from 'react';
import { render } from 'react-dom';
import {
  ApolloClient,
  InMemoryCache,
  ApolloProvider,
  useQuery,
  gql
} from "@apollo/client";

const client = new ApolloClient({
  uri: 'https://48p1r2roz4.sse.codesandbox.io',
  cache: new InMemoryCache()
});

function App() {
  return (
    <div>
      <h2>My first Apollo app 🚀</h2>
    </div>
  );
}

render(

  <ApolloProvider client={client}>
    <App />
  </ApolloProvider>,
  document.getElementById('root'),
);

참고
GraphQL 공식 문서
Apollo 공식 문서
얄코 GraphQL, Apollo

profile
오늘의 람다

0개의 댓글