본문 바로가기

Dev. Etc/knowledge

GraphQL의 개념 및 특징 (RESTful API 비교)

 

 

 

 

 

 

 

 

● GraphQL(Graph Query Language)이란?

Facebook에서 만든 어플리케이션 레이어 쿼리 언어입니다.

기존의 웹 or 모바일 어플리케이션의 API를 구현 할때는, 통상적으로 RESTful API가 사용됩니다.

기존의 RESTful API를 사용하여 API를 구현한다면 우리가 클라이언트사이드에서 어떠한 기능이 필요할 떄마다 그때 새로운 API를 만들어주어야했습니다.

즉, 단일 요청으로 많은 데이터를 얻을 수 있습니다.

 

 

 

※ 기존 RESTful API의 문제들

  • Atomic한 REST API라는 큰 장점의 이면에 클라이언트의 코드는 점점 복잡해지고 있습니다. 기능이 추가될때마다 end-point는 점점 늘어나고 화면을 그리기 위해 REST API 응답간 의존성을 핸들링하기 위한 코드와 각종 유틸함수들이 늘어납니다. ( Under-Fetching / Over-Fetching )
  • 문서화의 부담이 있습니다. 예들을어 백엔드 팀 인원에 비해 너무 많은 업무를 하다보면 Redoc을 통해 생성되는 문서가 종종 불충분한 정보를 주거나 커뮤니케이션 비용이 늘어나게 됩니다. (graphQL은 스키마 자체가 문서로서 동작하기에 별도의 문서화과정이 불필요하고 각각 스키마가 갖는 상관 관계를 graphql-voyager를 통해 모델간의 관계를 도식화하여 용이아게 파악할 수 있는 부가적인 장점도 가져갈 수 있었습니다.)

 

 

※ GraphQL의 장점

  • Front End단에서 필요한 최소한의 정보만 별도 요청이 가능하기에 효율적이고 각 장비에서의 퍼포먼스를 향상시킬 수 있습니다. (HTTP 요청의 횟수를 줄일수있음)
  • 엄격하게 정의된 데이터 유형은 클라이언트와 서버 간의 통신 오류를 줄여줍니다.
  • GraphQL은 애플리케이션 API가 기존 쿼리를 중단하지 않고도 진화할 수 있도록 허용합니다. (무중단 배포)
  • REST API로 사용할 수 없는 기능을 제공하기 위해 대부분의 오픈소스 GraphQL 확장 기능을 사용할 수 있습니다.
  • REST API는 Resource 종류별로 요청을 해야하고, 이로인해 요청 횟수가 필요한 Resource의 종류에 비례합니다. 반면에 GraphQL은 원하는 정보를 하나의 Query에 모두 담아 요청하는 것이 가능하기에 HTTP 응답의 Size를 줄일 수 있습니다.
  • REST API에서의 한계인 Over-Fetching과 Under-Fetching을 개선해줍니다.

 

 

※ GraphQL의 단점

  • File 전송 등 Text만으로 하기 힘든 작업들을 처리하기 복잡합니다.
  • HTTP와 HTTPs에 의한 Caching이 REST보다 복잡합니다.
  • 고정된 요청과 응답만 필요할 경우에는 Query 로 인해 요청의 크기가 RESTful API 의 경우보다 더 커진다.
  • API 유지관리자의 경우 유지 관리 가능한 GraphQL 스키마를 작성하기 위한 추가 태스크를 수행해야 하기에 익숙하지 않은 개발자는 작업 시간이 다소 소요됩니다. (단, 개발자간의 불필요한 커뮤니케이션 비용절감 가능)

 

https://ssungkang.tistory.com/entry/WEB-GraphQL-REST-API%EC%9D%98-%EB%8C%80%EC%B2%B4

 

출처: https://www.97vsshop.com/index.php?route=product/category&cid=178&cname=graphql+java+client

 

 

 

* GraphQL에서 파일 업로드가 복잡한 이유 및 방안
일반적으로 REST API를 사용하여 JSON 형식의 데이터를 전송할 경우에는 ContentType을 application/json으로, 파일의 경우에는 multipart/form-data으로 설정합니다. 여기서 ContentType이란 HTTP에서 body에 실리는 데이터의 타입을 말하고 서버에서는 이를 확인하여 타입에 맞게 데이터를 Parsing 합니다.
GraphQL의 쿼리는 json형식을 따르기 때문에 항상 ContentType이 application/json인 요청을 해야 합니다.
두 데이터 형식의 차이를 메워 줄 미들웨어가 필요하고 이 미들웨어가 클라이언트로부터 multipart/form-data 형식의 데이터를 캐치하여 GraphQL이 이해할 수 있는 JSON 형식으로 바꾸어 전달해 주는 역할을 합니다.


GraphQL에서 파일 업로드 작업을 하기위해서 여러 방안이 있습니다.
1.apollo-server-express에서 제공해주는 GraphQLUpload type을 사용할 것. (사용 예시 바로가기)
단, node 최신버전 지원하지 않아 node version 12로 변경할것.
2. npm을 통해 graphql-upload라는 것을 install하여 작업. (사용 예시 바로가기) // 1주에 약 70만 다운로드

 

* Apollo란?
Apollo는 GraphQL을 편하게 사용할 수 있도록 도와주는 라이브러리 입니다.
Apollo Server는 GraphQL이 적용된 서버를 생성할 수 있는 클래스를 제공한다. 비유하자면 create-react-app 패키지와 비슷한 역할이다.

Apollo는 client와 server 모두에서 사용이 가능합니다. 공식 홈페이지에서 apollo client는 상태관리 라이브러리로 react redux를, apolo server는 REST API 를 대체할 수 있을 것이라고 소개하고 있습니다.

 


■ Over-Fetching
: 클라이언트의 요구사항보다 더 많은 데이터를 반환하는 경우를 말합니다.
예를 들어 생각해봅시다.
서버 개발자는 User의 여러 정보를 반환하는 API를 만들었습니다.
클라이언트는 User의 name 필드만 필요해도 API를 호출해야하고 불필요한 데이터가 많이 넘어오게 됩니다.
또는 새로운 API를 개발해야합니다.

 

 Under-Fetching
: 클라이언트에서 원하는 데이터들을 위해 여러 API를 호출하는 것을 말합니다.
한 번의 Request에 원하는 데이터가 한 번에 오지 않을 경우 입니다.
블로그의 경우를 예로 들자면 
블로그 글의 목록과 일부 내용(post), 블로그 타이틀(blog), 경우에 따라 로그인한 user 정보 등의 여러 Resource가 있기 때문에 RESTful 한 API를 개발한다면, 각 Resouce에 맞게 GET API를 fetch 해주어야 합니다.
반면 GraphQL은 REST와는 다르기 때문에 클라이언트(프론트 엔드단)에서 얼마든지 필요한 데이터를 쿼리할 수 있습니다. post, blog, user 등의 Resource를 한 번에 Query로 받아올 수 있는 것 입니다.

 

 


 

● GraphQL과 RESTful API의 간단한 비교 예시

특정 사람에 대한 이름, 키, 성별만 가져온다고 가정합니다.

 

REST API

 

요청

method : get

end-point : https://choseongho93.com/api/user/1 

 

결과

{
  "name": "nate",
  "height": "187",
  "hair_color": "blond",
  "skin_color": "fair",
  "eye_color": "blue",
  "gender": "male",
  "study": [3,4,21,23,31],
  "created": "2014-12-09T13:50:51.644000Z",
  "edited": "2014-12-20T21:17:56.891000Z",
}

불필요한 데이터가 너무 많이 포함되어 전송되었습니다.

 

GraphQL

 

요청

end-point : https://choseongho93.com/graphql

query {
  users(userId: 1) {
    name
    height
    gender
  }
}

 

결과

{
  "data": {
    "person": {
      "name": "nate",
      "height": 187,
      "gender": "male"
    }
  }
}

RESTful API와 달리 원하는 필드만 불러올 수 있습니다.

여기서 서버에서 전송하는 데이터 양을 줄여 성능을 높일 수 있습니다.

 

 


 

 

 

 

그렇다면, GraphQL or RESTful API 둘중 어떤것을 사용하는 것이 좋을까?

  1. GraphQL
    • 서로 다른 모양의 다양한 요청들에 대해 응답할 수 있어야 할 때
    • 대부분의 요청이 CRUD에 해당할 때
  2. RESTful
    • HTTP 와 HTTPs 에 의한 Caching 을 잘 사용하고 싶을 때
    • File 전송 등 단순한 Text 로 처리되지 않는 요청들이 있을 때
    • 요청의 구조가 명확하게 정해져 있을 때 ( 요구사항 변동이 거의 없는 경우.....)

즉, 둘 중 하나를 선택할 필요는 없다는 것입니다.

예를 들어 하나의 Endpoint를 GraphQL용으로 만들고, 다른 RESTful API용 Endpoint를 만들어 놓아도 됩니다.

하지만, 하나의 목표를 위해 2가지 API 구조를 섞어놓는 것은 API의 품질을 떨어트릴 수 있다는 점입니다.

(예로 들면 사용자 정보를 등록하는 것은 RESTful API 로, 사용자 정보를 수정하는 것은 GraphQL API로.)

 

 

 

 

 

 


 

 

 

 

ref: https://ssungkang.tistory.com/entry/WEB-GraphQL-REST-API%EC%9D%98-%EB%8C%80%EC%B2%B4

https://velog.io/@djaxornwkd12/REST-API-vs-GraphQL-%EC%B0%A8%EC%9D%B4%EC%A0%90-%EC%95%8C%EC%95%84%EB%B3%B4%EA%B8%B0

https://www.npmjs.com/package/graphql-upload#class-graphqlupload

https://velog.io/@hanjn2842/NestJsGraphQL-File-Upload