graphql-compose 커스텀 리졸버에 리턴 타입 추가하기

ToastEggsToast·2021년 6월 19일
0

graphql-compose

graphql-compose는 node.js에서 복잡한 graphql 스키마를 구성할 수 있도록 도와주는 라이브러리입니다.
스키마를 구성할 수 있도록 여러가지 리졸버(resolver), 타입 스키마를 제공합니다.

커스텀 리졸버의 타입

graphql-compose에서 제공하는 리졸버가 아닌, 유저가 직접 구성해서 작성한 리졸버로, 리턴되는 타입을 지정해줘야만 합니다.

커스텀 리졸버를 통해 제작되어있는 모델 타입 정보가 아닌, 일부 정보만 리턴하고자 할 때 타입을 지정하는 것이 어려웠고, type을 JSON으로 명시해주었을 경우, playground 등에서 원하는 정보만 얻기 어려웠다는 단점이 있었습니다.

해당 단점을 보완하고자 여러가지 리서치를 진행했고, createObjectTC 문서를 통해 해답을 얻을 수 있었습니다.

기존 코드

import { UserProductModel, UserTicketModel } from '~'; // 모델 스키마가 정의되어 있는 파일 루트
import { ProductModelTC } from '~'; // TC 가 정의되어 있는 파일 루트

const name = 'resolverName';

// args에는 해당 리졸버 쿼리를 보낼 때 함께 보내는 argument의 key 네임과 값의 타입을 지정해줍니다.

  ProductModelTC.addResolver({
    args: {
      id: 'String',
    },
    name,
    resolve: async ({ args }: { args: { id?: string } }) => {
      const item = await Model.findOne({
        uid: args.id,
      });

      if (!item) {
        throw new Error('올바르지 않은 상품 정보입니다. 다시 시도해주세요.');
      }

      const userTickets = await UserTicketModel.find({
        parentPackage: userProductPackage._id,
      });
      const userProducts = await UserProductModel.find({
        parentPackage: userProductPackage._id,
      });

      return {
        userPackage: userProductPackage,
        userTickets: userTickets,
        userProducts: userProducts,
      };
    },
    type: 'JSON',
  });

해당 리졸버는 Model을 통해 원하는 데이터를 받아 수정, 가공 된 타입의 데이터를 리턴하고 있습니다.
초기에는 타입을 지정해주지 못 해 JSON타입으로 값을 리턴하였고, playground 등에서 테스트를 진행할 때 따라오는 데이터 중 원하는 정보만 받아올 수 없었습니다.

createObjectTC를 이용해 수정된 코드

import { UserProductModel, UserTicketModel } from '~'; // 모델 스키마가 정의되어 있는 파일 루트
import { ProductModelTC } from '~'; // TC 가 정의되어 있는 파일 루트
import { schemaComposer } from 'graphql-compose';

const name = 'resolverName';

// 리턴될 데이터의 타입을 미리 지정해서, objectTC로 제작합니다. 
// userTickets, userProducts의 경우 단일 데이터가 아닌 배열 데이터로 리턴되어 배열([])로 감싸주었습니다.
// 해당 방식으로 데이터의 타입을 지정해 줄 경우, UserTickets의 _id만 받거나, 원하는 일부 데이터만 받아오는 것이 가능해집니다.
const ReturnType = schemaComposer.createObjectTC({
  name: 'returnType',
  fields: {
    userPackage: 'UserProduct',
    userTickets: '[UserTicket]',
    userProducts: '[UserProduct]',
  },
});

  ProductModelTC.addResolver({
    args: {
      id: 'String',
    },
    name,
    resolve: async ({ args }: { args: { id?: string } }) => {
      const item = await Model.findOne({
        uid: args.id,
      });

      if (!item) {
        throw new Error('올바르지 않은 상품 정보입니다. 다시 시도해주세요.');
      }

      const userTickets = await UserTicketModel.find({
        parentPackage: userProductPackage._id,
      });
      const userProducts = await UserProductModel.find({
        parentPackage: userProductPackage._id,
      });

      return {
        userPackage: userProductPackage,
        userTickets: userTickets,
        userProducts: userProducts,
      };
    },
    type: ReturnType,
  });

createObjectTC를 통해 리턴될 값의 스키마를 제작하고, 해당 스키마를 type에 작성해주었습니다.
타입을 JSON으로 지정해주었을 때와 다르게 query에 리턴되는 데이터 중 일부의 값만 받아올 수 있도록 하는 것이 가능해집니다.

profile
개발하는 반숙계란 / 하고싶은 공부를 합니다. 목적은 흥미입니다.

0개의 댓글