Skip to contentGraphQL
장점
조회 API 구성이 매우 빠름
- type에 필드를 추가하기만 하면 해당 type과 연관이 있는 모든 곳에서 사용 가능
- 이는 mutation에도 동일하게 적용되므로, 요청과 조회를 한 번에 할 수 있음
문서가 자동으로 작성됨
- Introspection에 의해 명세가 자동으로 생성되므로 문서가 자동으로 생김
필요한 필드만 요청할 수 있음
- 필요한 필드만 요청하므로 불필요한 요청이 감소
엔드포인트가 하나
- 엔드포인트가
/graphql
하나이므로 URL 하나만 관리하면 됨
각 edge별 필터링 가능
- edge - node로 연결되는 관계에서 필터링 사용 가능
단점
프론트엔드 부담이 커짐
- 프론트엔드에서 요청을 한 번에 끝내려고 무리하게 Depth를 파고들어가며 값을 가져오는 경우가 생김
- Depth 제한을 할 수 있지만 이미 사용하고 있는 레가시 쿼리에서 오류가 날 수 있음
- 프론트엔드에서 쿼리를 돌려쓰려다 지나치게 거대한 쿼리를 요청하는 경우가 있음
- 복잡도를 평가해 요청을 반려할 수 있지만 평가 방식에 따라 충분히 요청 가능한 쿼리도 반려될 수 있음
- 프론트엔드에서 type간 관계를 숙지하지 않으면 의사소통 비용이 커짐
- 백엔드에서 가이드를 주지 않으면 어떤 필드를 어디서 가져와야하는지 알기 쉽지 않아 무리한 쿼리를 만드는 경우가 있음
- 프론트엔드에서 fragment로 쿼리를 돌려 쓸 경우 불필요한 필드 요청이 많아짐
최적화가 힘듦
- 쿼리 요청을 전적으로 프론트엔드에게 맡기기 때문에, 백엔드에서 쿼리 최적화를 하기가 쉽지 않음
- 쿼리를 파싱해서 M2M 관계에서 prefetch를 걸거나, 이미 가져온 결과에 대해 캐싱하는것 정도만 가능
스키마 변경이 광역으로 일어남
- 쿼리가 관계성을 가지기 때문에, 한 곳의 type 추가/수정/삭제가 일어날 경우 해당 type과 관계가 있는 모든 쿼리가 영향을 받음
- 특히 필드 삭제, 이름 변경은 해당 필드를 쓰는 모든 쿼리를 점검해 봐야함
엔드포인트가 하나
- 기존의 많은 라이브러리/솔루션을 쓸 수 없음
- GraphQL APM 등은 아직 베타거나 기능이 부실한 경우가 많음 (ex: Datadog의 경우 많은 옵션이 사용 불가)
- 구분하려면 API별 로그가 아닌 내부 Body의 쿼리를 봐야함
- 엔드포인트로 권한 설정 불가, 각 type이나 field, mutation 별로 권한 설정을 해줘야함
에러 정책이 다름
- GraphQL 권장으로 HTTP 응답 코드가 통신 구간에 문제 없으면 에러가 발생했어도 200을 내려줌 (HTTP 응답 코드는 통신 구간 상태를 표시해줌)
- 즉 HTTP Status code는 200인데 내부 응답 에러코드는 404 NOT FOUND가 발생할 수 있음
- REST랑 혼합하여 사용할 경우 에러 처리 로직을 다르게 가져가야함
개발 테스트 도구 선택의 폭이 넓지 않음
- GraphiQL, GraphQL Playground, Altair GraphQL Client, Postman
- 이 중 파일 업로드를 지원하는 유일한 툴은 Altair GraphQL Client밖에 없음
type의 Custom Resolver로 인해 N+1 문제가 발생
- 이는 DRF에서 Output Serializer에 리졸버를 너무 많이 만들어도 동일한 문제가 발생함
- API별로 컨트롤 할 수 있는 DRF와 달리 GraphQL은 Custom Resolver가 type에 선언되므로, edge - node로 구성되는 M2M 관계나 역참조 관계에서 N+1이 일어나기 매우 쉬움