본문 바로가기
React

React에서 GraphQL Subscription 사용법 완벽 정리

by 굿센스굿 2024. 12. 17.
반응형

 

목차

  1. GraphQL Subscription이란?
  2. React에서 GraphQL Subscription 구현을 위한 준비
  3. GraphQL Subscription 기본 사용법
  4. 예제 프로젝트로 배우는 실전 구현
  5. 최적화 및 에러 핸들링
  6. 마치며

1. GraphQL Subscription이란?

GraphQL의 Subscription서버에서 실시간으로 데이터의 변경 사항을 클라이언트에 전달하는 기능입니다.
주로 채팅 애플리케이션, 실시간 알림, 대시보드와 같이 데이터가 자주 업데이트되는 환경에서 사용됩니다.

GraphQL의 Query와 Mutation은 클라이언트가 요청할 때 서버에서 응답하는 반면, Subscription은 데이터가 변경될 때마다 서버가 클라이언트로 푸시하는 방식으로 작동합니다.
이로 인해 React 애플리케이션에서 실시간 기능을 구현할 때 매우 유용합니다.


2. React에서 GraphQL Subscription 구현을 위한 준비

React 애플리케이션에서 GraphQL Subscription을 구현하기 위해 다음과 같은 도구들이 필요합니다.

필수 라이브러리 설치

  1. Apollo Client: React에서 GraphQL 클라이언트를 구현하기 위한 도구입니다.
  2. GraphQL: GraphQL 언어 지원 라이브러리입니다.
  3. Subscriptions-Transport-WS: WebSocket을 통한 Subscription 통신을 지원합니다.
npm install @apollo/client graphql subscriptions-transport-ws

Apollo Client 설정

GraphQL Subscription을 사용하려면 WebSocket을 설정해줘야 합니다.

아래는 Apollo Client와 WebSocket을 설정하는 코드 예시입니다.

import React from 'react';
import { ApolloClient, InMemoryCache, ApolloProvider, split, HttpLink } from '@apollo/client';
import { getMainDefinition } from '@apollo/client/utilities';
import { WebSocketLink } from '@apollo/client/link/ws';

const httpLink = new HttpLink({
  uri: 'http://localhost:4000/graphql', // GraphQL 서버 URL
});

const wsLink = new WebSocketLink({
  uri: 'ws://localhost:4000/graphql', // WebSocket 서버 URL
  options: {
    reconnect: true, // 재연결 옵션
  },
});

// HTTP와 WebSocket 링크를 분리
const splitLink = split(
  ({ query }) => {
    const definition = getMainDefinition(query);
    return (
      definition.kind === 'OperationDefinition' &&
      definition.operation === 'subscription'
    );
  },
  wsLink,
  httpLink
);

// Apollo Client 설정
const client = new ApolloClient({
  link: splitLink,
  cache: new InMemoryCache(),
});

function App({ children }) {
  return <ApolloProvider client={client}>{children}</ApolloProvider>;
}

export default App;

이제 Apollo Client를 통해 HTTP와 WebSocket을 모두 지원하는 환경이 준비되었습니다.


3. GraphQL Subscription 기본 사용법

GraphQL Subscription을 구현하기 위해 useSubscription 훅을 사용합니다.

다음은 기본적인 사용 예제입니다.

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

const NEW_MESSAGES = gql`
  subscription OnNewMessage {
    newMessage {
      id
      content
      sender
    }
  }
`;

function MessageList() {
  const { data, loading, error } = useSubscription(NEW_MESSAGES);

  if (loading) return <p>로딩 중...</p>;
  if (error) return <p>에러: {error.message}</p>;

  return (
    <div>
      <h3>실시간 메시지</h3>
      {data && data.newMessage && (
        <p>
          <strong>{data.newMessage.sender}:</strong> {data.newMessage.content}
        </p>
      )}
    </div>
  );
}

export default MessageList;

코드 설명

  1. gql: GraphQL 쿼리 문자열을 정의합니다.
  2. useSubscription: Subscription을 처리하는 React 훅입니다.
  3. loading: Subscription 연결 상태를 보여줍니다.
  4. data: 서버에서 전송된 데이터입니다.
  5. error: 오류가 발생한 경우 에러를 반환합니다.

4. 예제 프로젝트로 배우는 실전 구현

실시간 채팅 예제

간단한 실시간 채팅 애플리케이션을 구현해보겠습니다.

  1. GraphQL Subscription 스키마

먼저 서버 측에서 Subscription을 설정해야 합니다.

type Message {
  id: ID!
  content: String!
  sender: String!
}

type Subscription {
  newMessage: Message!
}

type Mutation {
  sendMessage(content: String!, sender: String!): Message!
}
  1. React 클라이언트 구현

메시지 송신 및 실시간 수신 기능을 구현합니다.

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

const NEW_MESSAGES = gql`
  subscription OnNewMessage {
    newMessage {
      id
      content
      sender
    }
  }
`;

const SEND_MESSAGE = gql`
  mutation SendMessage($content: String!, $sender: String!) {
    sendMessage(content: $content, sender: $sender) {
      id
      content
      sender
    }
  }
`;

function Chat() {
  const { data } = useSubscription(NEW_MESSAGES);
  const [sendMessage] = useMutation(SEND_MESSAGE);

  const [content, setContent] = useState('');
  const [sender, setSender] = useState('');

  const handleSubmit = (e) => {
    e.preventDefault();
    sendMessage({ variables: { content, sender } });
    setContent('');
  };

  return (
    <div>
      <h2>실시간 채팅</h2>
      <form onSubmit={handleSubmit}>
        <input
          type="text"
          placeholder="이름"
          value={sender}
          onChange={(e) => setSender(e.target.value)}
        />
        <input
          type="text"
          placeholder="메시지"
          value={content}
          onChange={(e) => setContent(e.target.value)}
        />
        <button type="submit">전송</button>
      </form>
      <div>
        <h3>메시지 목록</h3>
        {data &&
          data.newMessage && (
            <p>
              <strong>{data.newMessage.sender}:</strong> {data.newMessage.content}
            </p>
          )}
      </div>
    </div>
  );
}

export default Chat;

5. 최적화 및 에러 핸들링

GraphQL Subscription을 사용할 때 발생할 수 있는 주요 문제와 최적화 방법은 다음과 같습니다.

  1. WebSocket 연결 재시도: reconnect 옵션을 통해 서버 재시작 시 자동으로 재연결합니다.
  2. 로딩 및 에러 처리: useSubscription 훅에서 반환하는 loading과 error를 적절히 처리해야 합니다.
  3. 메모리 누수 방지: 컴포넌트 언마운트 시 Subscription을 해제해야 합니다. Apollo Client가 이를 자동으로 관리하지만, 가끔 명확히 언마운트를 확인하는 것이 좋습니다.

6. 마치며

React와 GraphQL Subscription을 결합하면 실시간 기능을 쉽게 구현할 수 있습니다.
Apollo ClientWebSocketLink를 사용하면 개발자가 복잡한 설정 없이 효율적으로 작업할 수 있습니다.

이번 블로그를 통해 실시간 채팅 예제를 만들어보면서 Subscription의 사용법을 명확히 이해하셨을 겁니다.
이를 바탕으로 실시간 알림, 대시보드 등 다양한 실시간 애플리케이션을 구현해보세요! 🚀


추가 팁: WebSocket 서버 최적화 및 성능 개선에 대한 내용도 다음 블로그에서 다룰 예정이니 기대해주세요!

반응형