개발새발 로그

GraphQL에 대하여 본문

카테고리 없음

GraphQL에 대하여

이즈흐 2023. 12. 19. 17:27

 

GraphQL은 뭘까?

GrapQL은 Rest API와 많이 비교가 되고있다.

먼저 Rest API와 동일하게 데이터를 불러오는 규칙이라고 할 수 있다.

- http 프로토콜을 사용한다는 점은 같다.

- 하지만 데이터를 가져오는 방법이 서로 다르다.

 

 

GraphQL이 필요한 이유?

Rest API의 한계를 극복하기 위해 등장했다.

 

- Over-Fetching

특정 데이터를 받기 위해 필요없는 데이터까지 불러올 수 있다.

 

- Under-Fetching

페이지에 필요한 데이터를 받아오기 위해 여러 API를 호출해야한다.

 

 

위 문제들을 GraphQL은 어떻게 해결 할까?

- GraphQL은 쿼리 문법을 이용해서 필요한 데이터만 불러올 수 있다.

- 네트워크 비용을 아낀다!

 

- 쿼리안에서 페이지에 필요한 데이터를 한번에 받아올 수 있다.

 

 

 

GraphQL 사용방법

 

먼저 GraphQL은 좋아보이는 만큼 지켜야할 기본적인 규칙이 있다.

 

1. 항상 `POST /graphql`로 요청한다.

2. 백엔드에서 타입을 정의해야한다.

- query로 user데이터를 오른쪽과 같이 요청하면 사실상 백엔드는 무슨 요청인지 모른다.

- 그렇기 때문에 백엔드에서는 어떤 query들이 있는지, 어떤 타입들이 있는지 미리 정의를 해둬야한다.

- 그리고 클라이언트도 정의된 타입을 알아야한다.

 

 

3. 요청은 querry, 변경은 mutation을 사용한다.

 

대체로 백엔드 개발자가 귀찮아지는 작업들이 꽤 있다.

GraphQL을 이용하는 서버가 잘 되어있으면 클라이언트 개발자는 매우 편하다.

 

 

 

 

GraphQL의 단점

- 러닝커브가 Rest API에 비해 높다. - 알아야할 게 많다.

- HTTP 캐싱 문제 - URI가 다 다르다면 URI를 통해 캐싱을 하면 되지만 GraphQl은 URI가 같아서 캐싱이 애매해짐 

 -> 별도의 라이브러리로 해결 가능

- 필요한 필드를 모두 작성해야한다.

- 파일 업로드에 대한 명쾌한 방법이 없음 - Rest API를 이용하거나 플러그인을 이용해야하는데 명쾌한 해답이 없다.

 

 

 

GraphQL에 대해 자세히 살펴보기

Query

가장 간단하게 GraphQL은 객체의 특정 필드를 요청하는 것입니다.

아주 간단한 쿼리와 이를 실행하면 어떤 결과가 나오는지부터 살펴보겠습니다:

GraphQL 쿼리는 관련 객체와 해당 필드를 순회할 수 있으므로 클라이언트는 기존 REST 아키텍처에서와 같이 여러 번 왕복하는 대신 한 번의 요청으로 많은 관련 데이터를 가져올 수 있습니다.

Query의 인수 활용

이는 Rest API와 유사하지만 GraphQL은 필드에도 인자를 넣어줄 수 있다

- 단위에 대한 것이다.

 

 

Query이름 지정

위의 몇 가지 예제에서는 쿼리 키워드와 쿼리 이름을 모두 생략하는 속기 구문을 사용했지만, 프로덕션 앱에서는 코드를 덜 모호하게 만들기 위해 이러한 구문을 사용하는 것이 유용합니다.

작업 이름은 작업에 대한 의미 있고 명시적인 이름입니다.

다중 작업 문서에서만 필요하지만 디버깅 및 서버 측 로깅에 매우 유용하므로 사용을 권장합니다.

문제가 발생했을 때(네트워크 로그나 GraphQL 서버의 로그에 오류가 표시되는 경우) 내용을 해독하는 대신 코드베이스에서 쿼리를 이름으로 식별하는 것이 더 쉽습니다.

 

별칭

위 human데이터에서 만약 id가 1000인 데이터와 1001인 데이터를 가져오고 싶다면 human데이터는 같은 이름으로 중복하여 응답하게 될 것이다.

이는 JSON 규칙에 어긋난다.

그래서 GraphQL은 필드의 결과를 원하는 이름으로 바꾸는 별칭을 사용한다.

 

변수활용 가능

변수로 작업을 시작할 때는 세 가지 작업을 수행해야 합니다:

  1. 쿼리의 정적 값을 $변수 이름으로 바꿉니다.
  2. 쿼리에서 허용하는 변수 중 하나로 $variableName을 선언합니다.
  3. 별도의 전송별(보통 JSON) 변수 사전에서 variableName: 값을 전달합니다.

유형 선언 뒤에 기본값을 추가하여 쿼리의 변수에 기본값을 할당할 수도 있습니다.

프래그먼트

query를 요청할 때 필요한 필드이름을 모두 작성해야한다.

만약 필요한 필드가 많다면 너무 길어지게 된다.

프래그먼트는 재사용 가능한 단위다. 

프래그먼트를 사용하면 필드 집합을 구성한 다음 필요한 곳에 쿼리에 포함할 수 있습니다.

- 위처럼 fragment를 미리 정의하고, leftComparison 쿼리에서 프래그먼트를 사용해 요청한다.

 

프래그먼트에서는 변수도 사용가능하다.

 

 

지시어

위에서 변수를 사용하여 동적 쿼리를 구성할 때 수동 문자열 보간을 피할 수 있는 방법에 대해 설명했습니다.

인수에 변수를 전달하면 이러한 문제의 상당 부분을 해결할 수 있지만, 변수를 사용하여 쿼리의 구조와 모양을 동적으로 변경하는 방법도 필요할 수 있습니다.

핵심 GraphQL 사양에는 정확히 두 개의 지시어가 포함되어 있으며,

이 지시어는 사양을 준수하는 모든 GraphQL 서버 구현에서 지원되어야 합니다:

  • @include(if: Boolean) 인수가 true인 경우에만 결과에 이 필드를 포함합니다.
  • @skip(if: Boolean) 인수가 true인 경우 이 필드를 건너뛰십시오.

서버 구현에서 완전히 새로운 지시어를 정의하여 실험적인 기능을 추가할 수도 있습니다.

 

인라인 프래그먼트

 

- 위처럼 프래그먼트를 query 밖에서 별도로 선언하는 게 아닌 query 안에서 선언해주고 있다.

- 유니온 타입을 사용하는 경우에 많이 사용한다.

-  hero가 반환하는 타입이 Droid일 수도 human일 수도 있을 경우다.

- 일종의 분기같은 것이다.

 

 

Mutation

GraphQL에 대한 대부분의 논의는 데이터 가져오기에 초점을 맞추고 있지만, 완전한 데이터 플랫폼에는 서버 측 데이터를 수정할 수 있는 방법도 필요합니다.

물론 query를 통해 서버에서 몇가지의 사이드이첵트를 일으킬 수 있습니다.

하지만 되도록이면 변경을 발생시키는 작업은 명시적으로 Mutation을 사용해야합니다.

- quey와 거의 모두  유사하다.

 

조금 다른점 이라면 아래와 같다.

뮤테이션은 쿼리와 마찬가지로 여러 필드를 포함할 수 있습니다.
쿼리와 변이 사이에는 이름 외에 한 가지 중요한 차이점이 있습니다:
쿼리 필드는 병렬로 실행되는 반면, 뮤테이션 필드는 차례로 직렬로 실행됩니다.
즉, 하나의 요청에 두 개의 incrementCredits 변형을 보내면 첫 번째 변형이 두 번째 변형을 시작하기 전에 완료되도록 보장하여 우리 자신과 경쟁 상태가 되지 않도록 합니다.

 

 

 

 

메타 필드

__typename을 요청하면 결과를 통해 내려온 타입을 확인할 수 있다.

 

 

728x90
반응형
LIST