자바스크립트 개발자를 위한 GraphQL Subscriptions 도입 방법

GraphQL은 클라이언트와 서버 간의 효율적인 데이터 통신을 제공하는 쿼리 언어입니다. 일반적으로 GraphQL은 클라이언트에서 서버로 데이터를 요청하는데 사용됩니다. 그러나 GraphQL Subscriptions를 사용하면 서버에서 클라이언트로 실시간 데이터 업데이트를 보낼 수 있습니다. 이는 실시간 알림, 채팅, 실시간 대시보드 등의 기능을 구현할 때 유용합니다.

이번 글에서는 자바스크립트 개발자를 위한 GraphQL Subscriptions를 도입하는 방법에 대해 알아보겠습니다.

1. GraphQL Subscriptions 설치

먼저, 프로젝트에 GraphQL Subscriptions를 설치해야 합니다. 아래의 명령어를 사용하여 필요한 패키지를 설치할 수 있습니다.

npm install graphql-subscriptions subscriptions-transport-ws

2. GraphQL Subscriptions 설정

GraphQL Subscriptions를 사용하려면 서버에 WebSocket 연결을 지원하는 기능을 추가해야 합니다. 일반적으로 Apollo ServerGraphQL Yoga와 같은 GraphQL 서버 라이브러리를 사용하는 것이 좋습니다.

이제 다음 단계를 따라 WebSocket 연결을 설정합니다.

Apollo Server 설정 예시

const { ApolloServer } = require('apollo-server');
const { execute, subscribe } = require('graphql');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const schema = require('./path/to/schema');

const server = new ApolloServer({
  schema,
});

server.listen().then(({ url, subscriptionsUrl }) => {
  console.log(`Server ready at ${url}`);
  console.log(`Subscriptions ready at ${subscriptionsUrl}`);
  new SubscriptionServer(
    {
      execute,
      subscribe,
      schema,
    },
    {
      server: server.httpServer,
      path: server.subscriptionsPath,
    }
  );
});

GraphQL Yoga 설정 예시

const { GraphQLServer } = require('graphql-yoga');
const { execute, subscribe } = require('graphql');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const schema = require('./path/to/schema');

const server = new GraphQLServer({
  schema,
});

server.start({ subscription: { path: '/subscriptions' } }, ({ port }) => {
  console.log(`Server started on http://localhost:${port}`);
  new SubscriptionServer(
    {
      execute,
      subscribe,
      schema,
    },
    {
      server: server.express,
      path: '/subscriptions',
    }
  );
});

설정이 완료되면 GraphQL Subscriptions를 사용할 수 있습니다.

3. Subscription 타입 및 리졸버 추가

이제 GraphQL 스키마에 Subscription 타입을 추가하고 해당 타입에 대한 리졸버를 작성해야 합니다. Subscription 타입은 실시간 데이터를 전송하기 위한 메시지를 정의하고, 리졸버는 해당 메시지를 보내는 역할을 합니다.

예제를 통해 Subscription 타입 및 리졸버 작성 방법을 살펴보겠습니다.

type Subscription {
  newMessage: Message
}

type Message {
  id: ID!
  content: String!
  createdAt: String!
}
const { PubSub, withFilter } = require('graphql-subscriptions');
const pubsub = new PubSub();

const resolvers = {
  Subscription: {
    newMessage: {
      subscribe: withFilter(
        () => pubsub.asyncIterator('NEW_MESSAGE'),
        (payload, variables) => {
          // 필터링 로직을 정의합니다.
          // 해당 코드에서는 특정 사용자에게만 메시지를 전송하는 로직을 구현합니다.
          return payload.recipientId === variables.recipientId;
        }
      ),
    },
  },
};

pubsub.publish('NEW_MESSAGE', {
  recipientId: 'user1',
  newMessage: {
    id: 'message1',
    content: 'Hello, World!',
    createdAt: new Date(),
  },
});

위의 코드에서 newMessageMessage 타입의 객체를 반환하며, withFilter 함수를 사용하여 필터링 로직을 정의합니다. pubsub.publish 함수를 사용하여 실제로 전송되는 메시지를 만들 수 있습니다.

4. 클라이언트에서 Subscriptions 사용

이제 클라이언트에서 GraphQL Subscriptions를 사용할 수 있습니다. 일반적으로 Apollo Client, Relay, React-Apollo 등과 같은 클라이언트 라이브러리를 사용하는 것이 좋습니다.

Apollo Client를 사용하는 예시를 살펴보겠습니다.

import { gql, ApolloClient, InMemoryCache } from '@apollo/client';
import { WebSocketLink } from '@apollo/client/link/ws';

const client = new ApolloClient({
  cache: new InMemoryCache(),
  link: new WebSocketLink({
    uri: 'ws://localhost:4000/subscriptions',
    options: {
      reconnect: true,
    },
  }),
});

const subscription = gql`
  subscription ($recipientId: ID!) {
    newMessage(recipientId: $recipientId) {
      id
      content
      createdAt
    }
  }
`;

client.subscribe({
  query: subscription,
  variables: {
    recipientId: 'user1',
  },
}).subscribe({
  next: (response) => {
    console.log(response.data.newMessage);
  },
});

위의 코드에서 WebSocketLink를 사용하여 WebSocket 연결을 설정하고, ApolloClient를 만든 후 subscribe 함수를 호출하여 구독합니다. 구독 결과를 받기 위해 next 콜백을 사용할 수 있습니다.

이제 자바스크립트 개발자들도 GraphQL Subscriptions를 사용하여 실시간 기능을 구현할 수 있습니다.

참고 자료:

#GraphQL #JavaScript