본문 바로가기
코드스테이츠

3/28 일일정리 GraphQL

by 강물둘기 2023. 3. 28.

GraphQL

GraphQL(Graph Query Language)은 페이스북에서 만든 API를 위한 쿼리언어이다. GraphQL은 특정한 데이터나 스토리지에 귀속되어 있지 않으며 기존 코드와 데이터에 의해 대체된다.

기존에 사용하던 REST API의 한계를 극복하기 위해 제작된 GraphQL의 목적은 그래프 순회를 바탕으로 클라이언트가 서버로부터 효율적으로 데이터를 받아오는 것이다.  GraphQL에서는 모든 데이터가 그래프 형태로 연결되어 있다고 전제하고 이를 바탕으로 유연하게 클라이언트의 요청을 처리한다.

 

REST API의 한계

⓵ Overfetch

 REST API의 경우 사용자의 데이터를 요청할 때 필요없는 데이터까지 응답으로 받게된다.

예를 들면 클라이언트는 유저의 id만 필요한데 다른 많은 데이터들(이메일, 나이, 이름 등등..)이 전부 응답 데이터로 돌아온다. 이렇게 필요없는 데이터까지 모두 응답으로 돌아오기 때문에 리소스의 낭비가 발생하는데, 이러한 현상을 Overfetch라고 한다.

 

⓶ Underfetch

Underfetch의 경우 Overfetch와 반대로 클라이언트는 필요한 정보를 모두 확보하기 위하여 추가적인 요청을 보내야 한다. 필요한 데이터가 여러 엔드포인트에 분산되어 있는 경우 각각의 엔드포인트로 GET 요청을 보내서 데이터를 받아야 한다.

 

⓷ 클라이언트 구조 변경에 따른 데이터 수정

REST API에서는 자원의 크기와 형태를 서버에서 결정하기 때문에 클라이언트가 직접 데이터의 형태를 결정할 수 없다. 따라서 클라이언트의 구조가 변경되어서 필요한 데이터가 변할 경우 다른 엔드포인트로 변경된 데이터를 가져오거나 수정해야 한다.

 

GraphQL의 특징

GraphQL은 HTTP를 통해 API 서버로 요청을 보내고 응답을 받는다. 응답을 받을때 데이터를 JSON형태로 받는다. 

GraphQL은 엔드포인트를 하나만 사용한다. 클라이언트 쪽에서 쿼리문을 작성하여 필요한 데이터를 정의하여 요청하면 서버에서 서버 개발자가 작성한 각 필드에 대응하는 resolver 함수로 각 필드의 데이터를 조회할 수 있다. 

 

장점

⓵ 하나의 엔드포인트로 모든 요청을 보낸다. 모든 클라이언트 요청은 POST 메서드를 사용한다.

⓶ 원하는 데이터만 정해서 요청하여 알맞은 데이터를 받을 수 있어서 overfetch, underfetch 현상이 일어나지 않는다.

⓷ playground라는 GUI를 사용하여 resolver와 schema를 한눈에 파악할 수 있다.

⓸ 클라이언트의 구조가 바뀌어도 필요한 사항만 쿼리에 작성하면 되기 때문에 서버에 지장이 없다. 이러한 특성 때문에 클라이언트 확장에도 용이하다.

 

단점

⓵ GraphQL을 학습하는데 시간이 걸린다.

⓶ 캐싱이 REST API보다 훨씬 복잡하다.

⓷ 고정된 요청과 응답이 필요할 경우 REST API보다 요청의 크기가 커진다.

 

GraphQL 구조

쿼리(Query)

쿼리는 여러 필드들로 구성되어 있다.

클라이언트에서 왼쪽 코드처럼 쿼리문을 작성해서 요청하면 오른쪽과 같은 응답이 돌아온다. GraphQL에서는 요청과 응답이 동일한 구조로 되어있다.

 

쿼리문에 전달인자를 넣는 것도 가능하다.

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

위와 같이 작성하면 id가 1000인 human의 name과 height를 요청하는 것이다.

 

필드 이름을 중복해서 사용해야 하는 경우 별명을 붙여서 쿼리를 작성한다.

{
  empireHero: hero(episode: EMPIRE) {
    name
  }
  jediHero: hero(episode: JEDI) {
    name
  }
}

 

오퍼레이션 네임을 붙이면 인자를 받을 수 있다. 오퍼레이션 네임은 코드의 확실한 역할을 알 수 있기 때문에 유용하다.

출처 : https://smoh.tistory.com/296

query HeroNameAndFriends($episode: Episode) {
  hero(episode: $episode) {
    name
    friends {
      name
    }
  }
}

인자를 사용해서 유동적으로 요청을 보낼 수 있다.

 

Mutation

Query 가 데이터 요청을 하는 GET 메서드와 비슷하다면 Mutation은 데이터 수정을 하는 POST 메서드와 비슷하다.

mutation CreateReviewForEpisode($ep: Episode!, $review: ReviewInput!) {
  createReview(episode: $ep, review: $review) {
    stars
    commentary
  }
}

 

Resolver

요청에 대한 응답을 결정해주는 함수로 특정 타입(query, mutation, subscription등)의 로직을 작성한다. 스키마를 정의하면 그 스키마 필드에 사용되는 함수의 실제 행동을 Resolver에서 정의한다. 

const resolvers = {
  Query: { // **Query :** 저장된 데이터 가져오기 (REST 에 GET 과 비슷합니다.)
		getUser: async (_, { email, pw }) => {
			db.findOne({
				where: { email, pw }
			}) ... // 실제 디비에서 데이터를 가져오는 로직을 작성합니다. 
			...
		}
  },
  Mutation: { // **Mutation :** 저장된 데이터 수정하기 ( Create , Update , Delete )
		createUser: async (_, { email, pw, name }) => {
			...
		}
  }
  Subscription: { // **Subscription :** 실시간 업데이트
    newUser: async () => {
      ...
		}
  }
};

* Supscription은 특정 이벤트가 발생하면 서버가 대응하는 데이터를 클라이언트에 자동으로 푸시해주는 기능이다.

 

 

Reference

- https://tech.kakao.com/2019/08/01/graphql-basic/

- https://hanamon.kr/graphql%EC%9D%B4%EB%9E%80-api%EB%A5%BC-%EC%9C%84%ED%95%9C-%EC%BF%BC%EB%A6%AC-%EC%96%B8%EC%96%B4/

- https://smoh.tistory.com/296

'코드스테이츠' 카테고리의 다른 글

3/30 일일정리 Optimization  (0) 2023.03.30
3/29 TDD  (0) 2023.03.29
3/27 일일정리 CS 기초  (0) 2023.03.27
3/24 일일정리 React Hooks 적용하기  (0) 2023.03.24
3/23 일일정리 Custom Hook  (0) 2023.03.23

댓글