자바스크립트를 이용한 GraphQL Subscriptions 구현 방법

GraphQL은 클라이언트와 서버 간의 효율적인 데이터 통신을 지원하는 쿼리 언어입니다. 그리고 GraphQL Subscriptions는 실시간 데이터 업데이트를 위한 기능으로, 실시간으로 발생하는 이벤트에 대한 구독을 지원합니다. 이번 블로그 게시물에서는 자바스크립트를 사용하여 GraphQL Subscriptions를 구현하는 방법을 알아보겠습니다.

1. 서버 설정

먼저, GraphQL Subscriptions를 구현하기 위해서는 GraphQL 서버를 설정해야 합니다. Apollo Server를 사용하는 예제를 기준으로 설명하겠습니다. 아래와 같이 필요한 패키지를 설치합니다.

npm install apollo-server graphql-subscriptions subscriptions-transport-ws

그리고 서버 설정 파일을 작성합니다.

const { ApolloServer, gql } = require('apollo-server');
const { PubSub } = require('graphql-subscriptions');
const { SubscriptionServer } = require('subscriptions-transport-ws');
const { createServer } = require('http');

const pubsub = new PubSub();

const typeDefs = gql`
  type Query {
    hello: String
  }

  type Mutation {
    setMessage(message: String!): String
  }

  type Subscription {
    messageUpdated: String
  }
`;

const resolvers = {
  Query: {
    hello: () => 'Hello, world!'
  },
  Mutation: {
    setMessage: (_, { message }) => {
      pubsub.publish('MESSAGE_UPDATED', { messageUpdated: message });
      return 'Message sent';
    }
  },
  Subscription: {
    messageUpdated: {
      subscribe: () => pubsub.asyncIterator('MESSAGE_UPDATED')
    }
  }
};

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: { pubsub }
});

const httpServer = createServer();
server.applyMiddleware({ app: httpServer });

httpServer.listen({ port: 4000 }, () => {
  console.log(`Server ready at http://localhost:4000${server.graphqlPath}`);
  new SubscriptionServer(
    { subscriptionPath: '/subscriptions', execute, subscribe, schema: server.schema },
    { server: httpServer }
  );
});

위 예제에서는 PubSub 객체를 사용하여 메시지 업데이트 이벤트를 발행하고, asyncIterator를 사용하여 이벤트를 구독하고 있습니다.

2. 클라이언트 구현

이제 클라이언트에서 GraphQL Subscriptions를 구독하는 방법에 대해 알아보겠습니다. Apollo Client를 사용하는 예제를 기준으로 설명하겠습니다. 먼저 필요한 패키지를 설치합니다.

npm install apollo-client graphql subscriptions-transport-ws

그리고 클라이언트 설정 파일을 작성합니다.

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

const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql'
});

const wsLink = new WebSocketLink({
  uri: `ws://localhost:4000/subscriptions`,
  options: {
    reconnect: true
  }
});

const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' && definition.operation === 'subscription'
    );
  },
  wsLink,
  httpLink
);

const client = new ApolloClient({
  link: splitLink,
  cache: new InMemoryCache()
});

const MESSAGE_SUBSCRIPTION = gql`
  subscription {
    messageUpdated
  }
`;

const messageSubscription = client.subscribe({ query: MESSAGE_SUBSCRIPTION });

messageSubscription.subscribe({
  next(data) {
    console.log(data);
  }
});

위 예제에서는 WebSocketLink를 사용하여 WebSocket 연결을 설정하고, split 함수를 사용하여 쿼리 유형에 따라 적절한 링크를 선택하고 있습니다.

결론

이번 블로그 게시물에서는 자바스크립트를 사용하여 GraphQL Subscriptions를 구현하는 방법을 알아보았습니다. GraphQL Subscriptions를 활용하면 웹 애플리케이션에서 실시간 데이터 업데이트를 손쉽게 구현할 수 있습니다. 더 자세한 내용은 아폴로 서버 또는 아폴로 클라이언트 공식 문서를 참고하시기 바랍니다.

#GraphQL #Subscriptions