자라나라 개발머리

[GraphQL] reference resolver 의미/사용법 본문

GraphQL

[GraphQL] reference resolver 의미/사용법

iammindy 2024. 4. 7. 19:27

동료 개발자분이 entity 사용에 대한 질문을 주셨는데, 어영부영 대답을 드리긴 했으나 성에 차지 않았습니다.

이유는 reference resolver에 대한 개념이 제 머릿속에서 명확하지 않아서 였습니다. (사실 잘 몰랐습니다)

그런 기념으로 apollo federation의 reference resolver에 대해 정리해보고자 합니다. 🧐

 

reference resolver 란?

reference resolver는 entity를 사용할 때 꼭 구현해주어야 하는 resolver입니다.

그럼 entity는 무엇인가요?  entity는 여러 subgql에서 사용할 수 있는 객체 type을 말합니다.

 

예시로,

자사 제품의 정보를 제공해주는 product subgraph에서 Product type을 정의 했습니다.

이 product subgraph에선 이 Product type을 통해 자사 DB에서 정보를 가져와 클라이언트에게 제공하고 있었습니다.

 

이후 자사 제품의 리뷰를 제공하는 review subgraph을 제작하려고 하니, product subgraph의 Product type을 그대로 써야할 상황이 생겼습니다.

이때 review subgraph에서 product subgraph의 Product type을 사용하기 위해선 세가지 일을 해야합니다.

 

1. product subgraph의 schema에 @key directive를 통해 Product type이 entity임을 명시

2. product subgraph의 resolver에 Product type의 reference resolver 구현

3. review subgraph의 schema에 @key directive를 통해 Product type이 entity임을 명시

 

여기서 reference resolver의 개념이 나오게 됩니다.

모든 entity는 하나의 reference resolver를 가지고 있습니다.

어떠한 subgraph에서 해당 entity를 사용하더라도, 반드시 이 reference resolver를 거쳐 값을 반환해줍니다.

 

정리하면,

reference resolver는 특정 엔티티 전용 리졸버이고, 전달된 primery key를 통해, 값을 반환해주는 리졸버라고 정의할 수 있습니다.

 

reference resolver 사용법

 

예시로 들었던, Product type을 entity로 만들어보고, reference resolver를 구현해보겠습니다.

1. entity가 될 type 작성

# products subgraph의 schema
type Product {
  id: ID!
  name: String!
  price: Float!
}

 

 

2.  만든 type entity 만들기

# products subgraph의 schema
type Product @key(fields: "id") { #Product type이 entity임을 명시해줌
  id: ID!
  name: String!
  price: Float!
}

 

3. 리졸버에 reference resolver 작성

꼭 __resolveReference라는 객체 이름으로 작성해주어야합니다.

__resolverReference의 첫번째 인자에 클라이언트가 전달한 객체의 primery key가 있습니다.

이를 활용해서, __resolveReference 객체의 함수 return 값에 여러분이 제공하고자하는 값을 넣어주세요.

주로 DB 접근이나, API 요청으로 구현하게 됩니다.

// products subgraph의 resolver

const resolvers = {
  Product: {
    __resolveReference: (args) => {
        const id = args.id //클라이언트가 제공한 Product의 primery 값인 id 추출
        return await dataSources.productsDataSource.getProductById(id); //여기서 DB 접근이나 API 요청 로직을 추가한다
  },
};

 

 

4.  entity를 사용할 subgql에서 해당 type이 entity임을 명시

# review subgraph의 schema
type Product @key(fields: "id") { #Product type이 entity임을 명시해줌
  id: ID!
}

 

이렇게 마치면 review subgraph에서도, Product type을 사용할 수 있게 됩니다.