GraphQL resolver 도메인 분리하기

최근 오래된 프로젝트에 다시 손을 대면서, 여러가지 개선 사항들이 보였다.

발견된 문제 중 하나는, 여러개의 Query 와 Mutation 들이 하나의 파일에서 모두 리졸빙 되던 문제였다.

상황을 as-is 와 to-be 로 비교해보겠다.

  1. as-is
const resolvers: Resolvers = {
	Query: {
		concertList: async (parent, args, ctx) => {
      // Implementation
    },
    concert: async (parent, args, ctx) => {
      // Implementation
    },
    user: async (parent, args, ctx) => {
      // Implementation
    },
	},
	Mutation: {
    createConcert: async (parent, args, ctx) => {
      // Implementation
    },
    updateConcert: async (parent, args, ctx) => {
      // Implementation
    },
    removeConcert: async (parent, args, ctx) => {
      // Implementation
    },
    updateConcertTicket: async (parent, args, ctx) => {
      // Implementation
    },
    createConcertPoster: async (parent, args, ctx) => {
      // Implementation
    },
    updateConcertPoster: async (parent, args, ctx) => {
      // Implementation
    },
    createEmailAuthRequest: async (parent, args) => {
      // Implementation
    },
    authenticateEmailAuthRequest: async (parent, args) => {
      // Implementation
    },
  },
}

위의 예제와 같이 여러개의 도메인이 한 파일에서 리졸빙 되고 있었다

따라서 to-be와 같이 개선하였다

  1. to-be
/resolvers
  /user.ts
  /staff.ts
  /concert.ts
  /concertCategory.ts
  /auth.ts
  /emailAuth.ts
  index.ts

staffResolvers.ts

import { Resolvers } from 'your-types-path';

const staffResolvers: Resolvers = {
  Query: {
    // Add staff-related queries here
  },
  Mutation: {
    // Add staff-related mutations here
  },
};

export default staffResolvers;

concertResolvers.ts

import { Resolvers } from 'your-types-path';

const concertResolvers: Resolvers = {
  Query: {
    concertList: async (parent, args, ctx) => {
      // Implementation
    },
    concert: async (parent, args, ctx) => {
      // Implementation
    },
  },
  Mutation: {
    createConcert: async (parent, args, ctx) => {
      // Implementation
    },
    updateConcert: async (parent, args, ctx) => {
      // Implementation
    },
    removeConcert: async (parent, args, ctx) => {
      // Implementation
    },
    updateConcertTicket: async (parent, args, ctx) => {
      // Implementation
    },
    createConcertPoster: async (parent, args, ctx) => {
      // Implementation
    },
    updateConcertPoster: async (parent, args, ctx) => {
      // Implementation
    },
  },
};

export default concertResolvers;

너무 많은 예제는 생략하겠다.

그닥 어려운 개념은 아니고 결국 호스트가 되는 resolvers.ts 에서 다음과 같이 묶어주면 된다!

resolvers.ts

import userResolvers from './user';
import staffResolvers from './staff';
import concertResolvers from './concert';
import concertCategoryResolvers from './concertCategory';
import authResolvers from './auth';
import emailAuthResolvers from './emailAuth';

const resolvers = {
  Query: {
    ...userResolvers.Query,
    ...staffResolvers.Query,
    ...concertResolvers.Query,
    ...concertCategoryResolvers.Query,
  },
  Mutation: {
    ...userResolvers.Mutation,
    ...authResolvers.Mutation,
    ...emailAuthResolvers.Mutation,
    ...concertResolvers.Mutation,
    ...concertCategoryResolvers.Mutation,
  },
};

export default resolvers;

← Go home