pile·
백엔드·카카오 스타일 (지그재그)카카오 스타일 (지그재그)·

GraphQL 이해하기: (4) 리졸버 인자 - 1. source

GraphQL.js 리졸버의 첫 번째 인자인 source를 다룬 연재 글이다. 상위 필드가 반환한 값이 그대로 들어온다는 단순한 동작이지만, 그 값이 스키마의 타입과 전혀 달라도 문제없다는 점을 여러 형태로 보여준다. 그 특성이 타입 언어와 잘 맞지 않는 지점도 함께 짚는다.

핵심 포인트
  • 리졸버는 상위 필드에서 하위 필드 순서로 호출되며 source에는 상위 필드가 반환한 값이 들어간다.
  • 상위 필드가 없는 최상위 쿼리에는 실행 시 지정한 rootValue가 들어오지만 실무에서 쓴 적은 없다고 밝힌다.
  • 스키마의 타입과 구현체의 타입이 같지 않아도 동작한다. 클래스로 정의해보면 그 차이가 눈에 들어온다.
  • TypeScript는 필드만 같으면 같은 타입으로 보므로 클래스 인스턴스와 객체 리터럴을 섞어도 통과한다.
  • 극단적으로 상위에서 식별자만 담은 객체를 반환하고 모든 필드를 하위 리졸버에서 채우는 것도 가능하다.
  • 이 유연함은 코드를 처음 보는 사람에게 혼란을 줄 수 있고 타입 생성 도구와도 충돌한다.
상세 정리
  • 기본 동작: Java 쪽에서는 환경 객체의 getSource로 같은 값을 얻는다.
  • 예제 스키마: 사용자와 게시물 타입을 두고, 게시물은 작성자 식별자와 작성자 객체를 함께 갖는다.
  • 예제 구현: 목록 리졸버는 게시물 배열을 그대로 반환하고, 작성자 리졸버는 source에서 식별자를 꺼내 사용자 맵을 조회한다.
  • 첫 관찰: 스키마의 게시물 타입과 구현의 게시물 인터페이스가 명백히 다른데도 문제없이 동작한다.
  • 차이를 드러내기: 게시물을 클래스로 정의해 인스턴스를 만들면 스키마 타입과 다르다는 점이 분명해진다.
  • 타입 검사의 허점: TypeScript는 구조가 같으면 같은 타입으로 인정하므로, 클래스 인스턴스와 객체 리터럴을 섞어 배열에 담아도 컴파일이 통과한다.
  • 실행 결과: 그 배열을 순회하며 인스턴스 여부를 찍어보면 첫 항목만 참이고 나머지는 거짓이 나온다.
  • 극단적인 예: 목록 리졸버가 식별자만 담은 객체 배열을 반환하고, 식별자와 제목과 작성자 리졸버가 각각 그 값을 받아 원본에서 찾아 채우게 할 수도 있다.
  • 결론: 상위 필드가 반환하는 값이 GraphQL 타입과 무관해도 아무 문제가 없다.
  • Java 확인: DGS로 같은 구조를 만들어도 동작이 같다. DGS가 GraphQL Java 위에서 동작하므로 차이가 없다고 덧붙인다.
  • 부작용 1: 잘 활용하면 좋지만 코드를 새로 접한 사람에게는 혼란을 줄 수 있다.
  • 부작용 2: 타입 언어와 어울리지 않는 부분이 생긴다.
  • 구체적 충돌: 코드 생성기로 리졸버 타입을 지정하는 프로젝트에서는, 목록 리졸버가 반환하는 값에 non-null인 작성자 필드가 없다는 타입 에러가 나 어쩔 수 없이 any를 쓰고 있다고 밝힌다.
  • 호출 순서의 전제: 리졸버는 상위에서 하위 순으로 호출되므로 하위가 받는 값은 언제나 직전 상위가 반환한 것이다. 이 순서를 잡아야 source의 정체가 분명해진다.
  • 활용 여지: 상위에서 무거운 조회를 미루고 키만 넘긴 뒤 실제로 요청된 필드의 리졸버에서만 조회하도록 나눌 수 있다.
  • 대가: 대신 상위 리졸버의 반환값만 봐서는 어떤 필드가 어떻게 채워지는지 알 수 없어 코드를 따라 읽는 부담이 커진다.
왜 읽나리졸버가 받는 첫 인자의 정체가 모호했다면, 스키마 타입과 실제 전달 값이 별개라는 사실과 그것이 타입 도구와 부딪히는 지점까지 확인할 수 있다.
카카오 스타일 (지그재그)
카카오 스타일 (지그재그) 블로그
원문은 여기서 이어서 읽을 수 있어요
원문 읽기
읽음 (0)

이 글과 비슷한

  1. 백엔드·twilio-engTwilio Engineering·

    Programmable Messaging에서 Verify API로 마이그레이션하기

    Twilio의 Programmable Messaging API로 자체 OTP 솔루션을 운영하던 서비스가 Verify API로 전환하는 방법을 코드 예시와 함께 설명한다. Verify는 OTP 전송·검증을 위한 전용 API로, 전화번호 구매, 토큰 생성, DB 저장·만료 관리를 내부에서 처리해 개발자가 직접 구현할 코드를 크게 줄인다.

    요약 이어보기
    #authentication#twilio#sms+2
  2. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 2부

    포스타입 백엔드 엔지니어가 벡터 기반 개인화 추천 시스템을 실제 운영하며 맞닥뜨린 성능 장애와 용량 문제를 해결한 과정을 담은 2부다. 수백만 개의 벡터 KNN 검색이 피크 시간대에 전체 Elasticsearch 검색 성능을 흔드는 문제부터 클러스터 OOM 사태까지, 쿼리 최적화와 인프라 분리 두 가지 경로로 근본 해결에 이른다.

    요약 이어보기
    #elasticsearch#vector-search#recommendation-system+2
  3. 백엔드·포스타입포스타입·

    포스타입이 개인화 추천을 하는 방법 1부

    포스타입이 태그 기반 추천의 한계를 극복하고 벡터 임베딩 기반 개인화 추천 시스템을 구축한 과정을 담은 1부다. 유사한 콘텐츠가 다른 용어를 쓰거나 동일한 태그가 전혀 다른 톤의 콘텐츠를 가리키는 문제를 임베딩 벡터로 해결하고, OpenSearch의 HNSW ANN 검색으로 수백만 벡터를 실시간 검색하는 시스템을 구축해 구매율 15% 향상을 달성했다.

    요약 이어보기
    #opensearch#vector-search#recommendation-system+2