GraphQL 연재 3편으로, 클라이언트 요청에 맞는 데이터를 실제로 반환하는 리졸버를 다룬다. 리졸버가 모든 필드마다 상위에서 하위 순으로 호출되고, 정의하지 않은 필드는 기본 리졸버가 처리한다는 원리를 이해하면 결과를 원하는 대로 조작할 수 있다는 게 요지다. REST 컨트롤러와 무엇이 다른지도 함께 정리한다.
핵심 포인트- 리졸버는 필드 요청이 들어왔을 때 그 값을 제공하는 함수다. Java 진영에서는 데이터 페처라고 부른다.
- 스키마와 리졸버는 분리하는 편이 유지보수에 낫다. Node.js 는 GraphQL Tools 의 addResolversToSchema, Java 는 GraphQLCodeRegistry 가 그 분리를 돕는다.
- 리졸버는 요청된 모든 필드에 대해 호출되며 상위 필드부터 하위 필드 순으로 실행된다. 같은 레벨의 순서는 보장되지 않고, 사이드 이펙트가 있는 Mutation 만 순서대로 실행된다.
- 직접 정의하지 않은 필드는 기본 리졸버가 맡는다. 상위 필드가 반환한 객체에서 같은 이름의 프로퍼티를 꺼내주는 것이 전부다.
- REST 컨트롤러는 최상위 요청만 처리하지만 GraphQL 은 하위 필드에도 리졸버를 붙일 수 있다. 그 필요가 없다면 굳이 GraphQL 을 쓸 이유가 없다고 못 박는다.
상세 정리- 비동기로 데이터를 가져와야 하면 Promise 를 반환하면 된다. graphql 라이브러리가 이행을 기다렸다가 값을 넘긴다.
- REST 와의 대응 관계: GET 은 Query, POST 와 PUT, DELETE 는 Mutation 에 해당한다.
- 이름 짓기가 다르다. GraphQL 은 동사가 분리돼 있지 않아 API 이름을 함수명처럼 짓고, REST 는 명사를 신경 써 그룹화하고 컨트롤러도 그에 맞춰 나눈다. GraphQL 은 경로와 네임스페이스 개념이 없어 리졸버를 알아서 나눠야 한다.
- GraphQL 은 타입 체크가 내장되고 반환 형태가 일정하지만, HTTP 상태 코드를 쓰지 않아 리소스 없음과 권한 없음 같은 구분이 표준화돼 있지 않다.
- 예시 스키마는 Post 와 User 다. 순수 REST 라면 getPosts 가 author_id 만 주고 별도로 getUser 를 부르는 게 자연스럽지만, 실제로는 효율을 위해 author 도 같이 반환하되 목록에 필요 없는 전화번호는 빼게 된다. 결국 Post.author 의 User 와 Query.getUser 의 User 는 사실상 다른 타입이 된다.
- GraphQL 에서는 그 두 타입이 자연스럽게 하나로 이어지고, author 가 필요한 클라이언트만 요청해 요청받을 때만 DB 에 접근할 수 있다.
- 호출 순서 분석: 예시 쿼리 하나에 대해 Query.getPosts 부터 getPosts 각 항목의 author.name 까지 필드마다 리졸버가 불린다. 직접 정의한 것은 그중 5개뿐이고 나머지는 전부 기본 리졸버가 처리한다.
- 기본 리졸버 구현: GraphQL.js 의 defaultFieldResolver 는 source 가 객체 같거나 함수일 때 해당 필드명의 프로퍼티를 꺼내고, 그 값이 함수면 호출한다. Java 는 PropertyDataFetcher 가 같은 일을 한다.
- 응용: User 타입에 name 리졸버를 추가해 소문자로 바꾸면 getPosts 결과와 getUser 결과 양쪽에 모두 적용된다.
- 데이터는 어느 리졸버가 반환해도 된다. Post.author 대신 getPosts 가 author 를 붙여 반환해도 결과는 같지만, Post 를 반환하는 다른 API 가 있으면 그쪽에도 같은 구현을 넣어야 한다.
- 중복 호출 함정: getPosts 가 이미 author 를 담아 반환하는데 Post.author 리졸버도 정의돼 있으면 그 리졸버가 또 호출된다. author 를 구하며 DB 에 접근한다면 중복 조회가 된다. source.author 가 있으면 그대로 쓰도록 조건을 넣어 막는다.
- 같은 스키마를 GraphQL Java 로 구현한 예도 함께 실어 표현 방식은 달라도 리졸버 원리가 동일함을 보인다.
왜 읽나GraphQL 을 REST 처럼 얕게 쓰고 있던 백엔드 개발자에게 리졸버 호출 규칙과 중복 조회 함정을 짚어주는 글.