지금까지 REST api만 사용해오다가 GraphQL과 이를 편하게 사용하게 해주는 apollo를 같이 사용하는곳도 있어서 무슨 차이가 있고, 왜 생겨난건지 알아보았다.
GraphQL은 Facebook에서 만든 어플리케이션 레이어 쿼리 언어이다.
기존의 웹이나 모바일 어플리케이션의 api를 구현 할 때는, 통상저긍로 RESTful api를 많이들 사용한다.
기존의 RESTful API는 우리가 클라이언트 사이드에서 어떠한 기능이 필요할 떄마다 그때 새로운 API를 만들어주어야했다.
즉, 단일 요청으로 많은 데이터를 얻을 수 있다.
결국 필요한 것을 구체적으로 요청할 수 있다는 것이다.
우리는 평소에 REST API 에 따라서 HTTP 위에서 백과 프론트가 소통을 하였다.
그때 프론트가 백에게 요청하는 일의 대부분은 DB에 저장되어있는 데이터를 요청하는 일 인데, 요청이 되면 sql(Structured Query Language)을 이용해서 DB의 프론트가 요청한 API에 알맞은 데이터를 가져와서 보내주는 역할을 하였다.
그러나 GraphQL 에서는 클라이언트가 쿼리로 요청을 보내면 리소스를 조합을해서 원하는 데이터들만 보내주게 된다.
GraphQL은 REST api의 over fetching과 under fetching 개선
REST API라는 큰 장점의 이면에 클라이언트의 코드는 점점 복잡해지고 있다.
기능이 추가될때마다 end-point는 점점 늘어나고 화면을 그리기 위해 REST api 응답간 의존성을 핸들링하기 위한 코드와 각종 유틸함수들이 늘어나게 된다. ( Under-Fetching / Over-Fetching )
클라이언트의 요구사항보다 더 많은 데이터를 반환하는 경우를 말한다.
유저의 아이디만 필요한 경우, 아이디 뿐 아니라 다른 불필요한 많은 데이터까지 같이 받게 된다.
아니면 새로운 api를 만들어야 한다.
클라이언트에서 원하는 데이터들을 위해 여러 API를 호출하는 것을 말한다.
한 번의 Request에 원하는 데이터가 한 번에 오지 않을 경우이다.
블로그의 경우 글의 내용, 타이틀, 경우에 따라 로그인한 user 정보 등의 여러 Resource가 있기 때문에 RESTful 한 API를 개발한다면 각 Resouce에 맞게 GET API를 fetch 해주어야 한다.
반면 GraphQL은 REST와는 다르기 때문에 클라이언트에서 얼마든지 필요한 데이터를 쿼리할 수 있다.
post, blog, user 등의 Resource를 한 번에 Query로 받아올 수 있는 것이다.
일반적으로 REST API를 사용하여 JSON 형식의 데이터를 전송할 경우에는 ContentType을 application/json으로, 파일의 경우에는 multipart/form-data으로 설정한다. 여기서 ContentType이란 HTTP에서 body에 실리는 데이터의 타입을 말하고 서버에서는 이를 확인하여 타입에 맞게 데이터를 Parsing 한다.
GraphQL의 쿼리는 json형식을 따르기 때문에 항상 ContentType이 application/json인 요청을 해야 한다.
두 데이터 형식의 차이를 메워 줄 미들웨어가 필요하고 이 미들웨어가 클라이언트로부터 multipart/form-data 형식의 데이터를 캐치하여 GraphQL이 이해할 수 있는 JSON 형식으로 바꾸어 전달해 주는 역할을 한다.
1.apollo-server-express에서 제공해주는 GraphQLUpload type을 사용
단, node 최신버전 지원하지 않아 node version 12로 변경해야 한다.
2. npm을 통해 graphql-upload라는 것을 install하여 작업
요청
end-point : https://choseongho93.com/graphql
userId가 1인 유저의 name, height, gender만 요청하였다.
query {
users(userId: 1) {
name
height
gender
}
}
결과
원하는 값만 받았다.
{
"data": {
"person": {
"name": "nate",
"height": 187,
"gender": "male"
}
}
}
GraphQL
서로 다른 모양의 다양한 요청들에 대해 응답할 수 있어야 할 때
대부분의 요청이 CRUD에 해당할 때
RESTful
HTTP 와 HTTPs 에 의한 Caching 을 잘 사용하고 싶을 때
File 전송 등 단순한 Text 로 처리되지 않는 요청들이 있을 때
요청의 구조가 명확하게 정해져 있을 때 ( 요구사항 변동이 거의 없는 경우.....)
하나의 Endpoint를 GraphQL용으로 만들고, 다른 RESTful API용 Endpoint를 만들어 놓아도 된다.
하지만, 하나의 목표를 위해 2가지 API 구조를 섞어놓는 것은 API의 품질을 떨어트릴 수 있다는 점이 있다.
(예로 들면 사용자 정보를 등록하는 것은 RESTful API 로, 사용자 정보를 수정하는 것은 GraphQL API로.)
HTTP와 HTTPs에 의한 Caching이 REST보다 복잡하다?? API의 품질을 떨어트릴 수 있다는 점?? 이 두 부분에 대해서는 차후 알아보도록 해야겠다.