GraphQL Subscriptions를 이용한 자바스크립트 실시간 게시판 개발하기

게시판은 사용자 간의 상호 작용과 실시간 업데이트를 필요로 하는 많은 웹 어플리케이션에서 일반적으로 사용됩니다. 이번 블로그 포스트에서는 GraphQL Subscriptions를 이용하여 자바스크립트로 실시간 게시판을 개발하는 방법을 알아보겠습니다.

GraphQL Subscriptions란?

GraphQL Subscriptions는 GraphQL의 일부로, 서버와 클라이언트 간에 실시간으로 데이터를 주고받을 수 있는 기능을 제공합니다. 이를 통해 실시간 업데이트와 이벤트 기반의 통신을 구현할 수 있습니다.

개발 환경 세팅

먼저 개발 환경을 세팅해야 합니다. 다음과 같은 도구들이 필요합니다:

  1. Node.js
  2. npm (Node Package Manager)

프로젝트 디렉토리를 생성한 후, 다음 명령어를 통해 필요한 패키지들을 설치합니다:

npm init -y
npm install graphql express apollo-server-express subscriptions-transport-ws

서버 셋업

이제 서버를 셋업해보겠습니다. index.js 파일을 생성하고 다음과 같이 작성합니다:

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

const typeDefs = gql`
  type Query {
    messages: [String]
  }

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

  type Subscription {
    newMessage: String
  }
`;

const resolvers = {
  Query: {
    messages: () => {
      // 구현 필요
    },
  },
  Mutation: {
    addMessage: (_, { message }) => {
      // 구현 필요
    },
  },
  Subscription: {
    newMessage: {
      subscribe: () => {
        // 구현 필요
      },
    },
  },
};

const PORT = 4000;
const app = express();

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

server.applyMiddleware({ app });

const httpServer = createServer(app);
httpServer.listen({ port: PORT }, () => {
  console.log(`Server ready at http://localhost:${PORT}${server.graphqlPath}`);
});

const wsServer = new SubscriptionServer(
  {
    execute,
    subscribe,
    schema: server.schema,
  },
  {
    server: httpServer,
    path: server.graphqlPath,
  }
);

Subscription 구현

이제 Subscription을 구현해보겠습니다. newMessage Subscription을 통해 실시간으로 새로운 메시지를 받아볼 수 있게 할 것입니다. Subscription 구현을 위해 graphql-subscriptions 패키지를 설치합니다:

npm install graphql-subscriptions

그리고 index.js 파일에 Subscription 관련 코드를 추가합니다:

const { PubSub } = require('graphql-subscriptions');

const pubsub = new PubSub();

const resolvers = {
  Subscription: {
    newMessage: {
      subscribe: () => pubsub.asyncIterator('NEW_MESSAGE'),
    },
  },
};

이제 addMessage 뮤테이션을 수정하여 새로운 메시지를 추가할 때마다 newMessage Subscription을 실행하도록 만들어보겠습니다:

const resolvers = {
  Mutation: {
    addMessage: (_, { message }) => {
      pubsub.publish('NEW_MESSAGE', { newMessage: message });
      return message;
    },
  },
};

클라이언트 셋업

마지막으로 클라이언트를 셋업해보겠습니다. index.html 파일을 생성하고 다음과 같이 작성합니다:

<!DOCTYPE html>
<html>
  <head>
    <title>Realtime Message Board</title>
    <script src="https://cdn.jsdelivr.net/npm/graphql-ws/dist/websocket.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/graphql-ws/dist/websocket-polyfill.js"></script>
  </head>
  <body>
    <ul id="messageList"></ul>

    <script>
      const messagesList = document.getElementById('messageList');

      const socket = new WebSocket('ws://localhost:4000/graphql');
      const subscriptionClient = new window.GraphQLWebSocket.SubscriptionClient('ws://localhost:4000/graphql', {
        reconnect: true,
        connectionParams: {},
      });

      subscriptionClient.request({
        query: `
          subscription {
            newMessage
          }
        `,
      }).subscribe({
        next: ({ data }) => {
          const newMessage = document.createElement('li');
          newMessage.textContent = data.newMessage;
          messagesList.appendChild(newMessage);
        },
      });
    </script>
  </body>
</html>

브라우저에서 index.html 파일을 열어보면, 실시간으로 업데이트되는 메시지를 확인할 수 있을 것입니다.

결론

이번 블로그 포스트에서는 GraphQL Subscriptions를 이용하여 자바스크립트로 실시간 게시판을 개발하는 방법을 알아보았습니다. GraphQL Subscriptions를 사용하면 사용자와의 상호 작용을 강화하고, 실시간으로 업데이트되는 정보를 제공할 수 있는 강력한 기능을 활용할 수 있습니다.

더 자세한 내용은 다음 레퍼런스를 참고해주세요:

#GraphQL #Subscriptions