GraphQL Subscriptions를 활용한 자바스크립트 실시간 공유 문서 편집 애플리케이션 개발하기

GraphQL은 API를 손쉽게 개발하고 사용할 수 있는 쿼리 언어입니다. GraphQL Subscriptions는 이러한 GraphQL을 사용하여 실시간 데이터를 손쉽게 전달할 수 있는 기능을 제공합니다. 이번 글에서는 GraphQL Subscriptions를 활용하여 자바스크립트로 실시간 공유 문서 편집 애플리케이션을 개발하는 방법에 대해 알아보겠습니다.

1. 개요

실시간 공유 문서 편집 애플리케이션은 여러 사용자가 동시에 같은 문서를 편집하는 기능을 제공하는 애플리케이션입니다. 사용자가 문서를 편집하면 실시간으로 다른 사용자들의 화면에도 변경 사항이 반영되는 것을 볼 수 있습니다.

2. 기술 스택

이번 프로젝트에서는 다음의 기술 스택을 사용합니다:

3. 백엔드 개발

3.1 GraphQL 서버 설정

먼저 Apollo Server를 사용하여 GraphQL 서버를 설정해야 합니다. 필요한 패키지를 설치하고, 스키마를 정의하고, Resolver 함수를 작성해야합니다. 이후 Subscription을 정의하는 부분을 추가해줍니다.

const { ApolloServer, PubSub } = require('apollo-server');

const pubsub = new PubSub();

const typeDefs = `
  type Document {
    id: ID!
    title: String!
    content: String!
  }

  type Query {
    document(id: ID!): Document
  }

  type Mutation {
    updateDocument(id: ID!, content: String!): Document
  }

  type Subscription {
    documentUpdated(id: ID!): Document
  }
`;

const resolvers = {
  Query: {
    document: (parent, { id }, context) => {
      // 문서 조회 로직
    },
  },
  Mutation: {
    updateDocument: async (parent, { id, content }, context) => {
      // 문서 업데이트 로직

      // 업데이트된 문서 정보를 publish
      const updatedDocument = { id, title: 'Updated Document', content };
      pubsub.publish('DOCUMENT_UPDATED', { documentUpdated: updatedDocument });

      return updatedDocument;
    },
  },
  Subscription: {
    documentUpdated: {
      subscribe: () => pubsub.asyncIterator('DOCUMENT_UPDATED'),
    },
  },
};

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

server.listen().then(({ url }) => {
  console.log(`GraphQL server is running at ${url}`);
});

3.2 데이터베이스 연동

백엔드에서는 데이터베이스를 사용하여 문서 데이터를 저장하고 조회합니다. 예를 들어 MongoDB를 사용한다고 가정하고, Mongoose를 통해 데이터베이스와 연동해보겠습니다.

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/myapp', { useNewUrlParser: true });

const documentSchema = new mongoose.Schema({
  title: String,
  content: String,
});

const DocumentModel = mongoose.model('Document', documentSchema);

const resolvers = {
  Query: {
    document: async (parent, { id }, context) => {
      const document = await DocumentModel.findById(id);
      return document;
    },
  },

  // Mutation 및 Subscription은 이전과 동일합니다.
};

4. 프론트엔드 개발

프론트엔드에서는 Apollo Client를 사용하여 GraphQL 서버와 통신하고, React를 사용하여 사용자 인터페이스를 구현합니다.

import React, { useState } from 'react';
import { gql, useQuery, useMutation, useSubscription } from '@apollo/client';

const GET_DOCUMENT = gql`
  query GetDocument($id: ID!) {
    document(id: $id) {
      id
      title
      content
    }
  }
`;

const UPDATE_DOCUMENT = gql`
  mutation UpdateDocument($id: ID!, $content: String!) {
    updateDocument(id: $id, content: $content) {
      id
      title
      content
    }
  }
`;

const DOCUMENT_UPDATED = gql`
  subscription DocumentUpdated($id: ID!) {
    documentUpdated(id: $id) {
      id
      title
      content
    }
  }
`;

function DocumentEditor({ documentId }) {
  const { loading, error, data } = useQuery(GET_DOCUMENT, { variables: { id: documentId } });
  const [content, setContent] = useState('');

  useSubscription(DOCUMENT_UPDATED, {
    variables: { id: documentId },
    onSubscriptionData: ({ subscriptionData }) => {
      const updatedDocument = subscriptionData.data.documentUpdated;
      setContent(updatedDocument.content);
    },
  });

  const [updateDocument] = useMutation(UPDATE_DOCUMENT);

  const handleChange = (event) => {
    setContent(event.target.value);
  };

  const handleSubmit = (event) => {
    event.preventDefault();
    updateDocument({ variables: { id: documentId, content } });
  };

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error!</div>;

  const { title, content } = data.document;

  return (
    <>
      <h1>{title}</h1>
      <form onSubmit={handleSubmit}>
        <textarea value={content} onChange={handleChange} />
        <button type="submit">Update Document</button>
      </form>
    </>
  );
}

5. 마무리

이번 글에서는 GraphQL Subscriptions를 활용하여 자바스크립트로 실시간 공유 문서 편집 애플리케이션을 개발하는 방법에 대해 알아보았습니다. Apollo Server와 Apollo Client를 사용하여 GraphQL을 구현하고, 실시간 데이터를 처리할 수 있도록 설정했습니다. 이를 통해 여러 사용자가 동시에 문서를 편집하는 애플리케이션을 손쉽게 구현할 수 있습니다. Happy coding!


참고 문서: