본문 바로가기

Study Information Technology

Spring Boot에서 GraphQL Subscription 서버 구현하기

728x90
반응형

Spring Boot에서 GraphQL Subscription 서버 구현하기

Overview

GraphQL은 API의 데이터를 효율적으로 쿼리할 수 있는 강력한 도구입니다. 특히, GraphQL의 Subscription 기능은 실시간 데이터 업데이트를 가능하게 합니다. 이 글에서는 Spring Boot를 사용하여 GraphQL Subscription 서버를 구현하는 방법에 대해 자세히 설명하겠습니다. 실시간 업데이트를 필요로 하는 애플리케이션, 예를 들어 채팅 애플리케이션이나 실시간 피드 알림 시스템에서 유용하게 사용될 수 있습니다.

Spring Boot에서 GraphQL Subscription 설정하기

  1. 프로젝트 설정

GraphQL Subscription을 구현하기 위해서는 Spring Boot와 GraphQL을 통합해야 합니다. Spring Boot 프로젝트를 생성할 때 Gradle 또는 Maven을 사용할 수 있습니다. Maven을 사용하는 경우 pom.xml 파일에 다음 의존성을 추가합니다:

<dependencies>
  <!-- GraphQL Dependencies -->
  <dependency>
    <groupId>com.graphql-java-kickstart</groupId>
    <artifactId>graphql-spring-boot-starter</artifactId>
    <version>12.0.0</version>
  </dependency>
  <dependency>
    <groupId>com.graphql-java-kickstart</groupId>
    <artifactId>graphql-java-kickstart-spring-boot-starter-subscriptions</artifactId>
    <version>12.0.0</version>
  </dependency>
  <!-- Spring Boot Dependencies -->
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
  </dependency>
  <!-- Other dependencies -->
</dependencies>

Gradle을 사용하는 경우 build.gradle 파일에 다음과 같은 의존성을 추가합니다:

dependencies {
implementation 'com.graphql-java-kickstart:graphql-spring-boot-starter:12.0.0'
implementation 'com.graphql-java-kickstart:graphql-java-kickstart-spring-boot-starter-subscriptions:12.0.0'
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// Other dependencies
}

위 의존성들은 Spring Boot와 GraphQL을 통합하는 데 필요한 핵심 라이브러리입니다.

  1. GraphQL 스키마 정의하기

GraphQL Subscription을 구현하기 위해서는 먼저 GraphQL 스키마를 정의해야 합니다. 스키마 파일(schema.graphqls)을 src/main/resources 디렉토리에 생성하고 다음과 같이 작성합니다:

type Query {
hello: String
}

type Subscription {
messageAdded: Message
}

type Message {
id: ID
content: String
timestamp: String
}

위 스키마에서는 messageAdded라는 Subscription을 정의했습니다. 이 Subscription은 새로운 메시지가 추가될 때마다 클라이언트에게 업데이트를 전송합니다.

  1. Subscription을 위한 GraphQL Resolver 작성하기

GraphQL Subscription을 처리하기 위해 Resolver를 작성해야 합니다. Spring Boot에서는 GraphQLSubscriptionResolver를 사용하여 Subscription을 처리할 수 있습니다. 아래는 MessageSubscriptionResolver라는 이름의 Subscription Resolver 예제입니다:

import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Sinks;

@Component
public class MessageSubscriptionResolver {

private final Sinks.Many<Message> sink = Sinks.many().multicast().onBackpressureBuffer();

public Flux<Message> messageAdded() {
return sink.asFlux();
}

public void addMessage(Message message) {
sink.tryEmitNext(message);
}
}

이 클래스에서는 messageAdded라는 Subscription을 처리하는 메서드와 새로운 메시지를 sink에 추가하는 addMessage 메서드를 정의했습니다. sink는 새로운 메시지를 클라이언트에게 전송하는 역할을 합니다.

  1. WebSocket 설정

GraphQL Subscription은 WebSocket을 통해 클라이언트와 서버 간의 실시간 통신을 가능하게 합니다. Spring Boot에서 WebSocket을 설정하려면 다음과 같은 설정 클래스를 작성합니다:

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebSocketConfig implements WebMvcConfigurer {

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/graphql").allowedOrigins("*");
}
}

이 설정은 WebSocket의 CORS 정책을 설정합니다. allowedOrigins("*")는 모든 출처에서 WebSocket 연결을 허용합니다. 보안 측면에서 필요한 경우, 특정 출처만 허용하도록 설정할 수 있습니다.

  1. GraphQL Server 구현

이제 GraphQL 서버를 구현할 준비가 되었습니다. Spring Boot 애플리케이션의 메인 클래스를 작성합니다:

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class GraphqlSubscriptionApplication {

public static void main(String[] args) {
SpringApplication.run(GraphqlSubscriptionApplication.class, args);
}
}

이 클래스를 통해 Spring Boot 애플리케이션이 실행됩니다.

  1. 클라이언트에서 Subscription 테스트

클라이언트에서는 GraphQL Subscription을 테스트할 수 있는 GraphQL Playground 또는 GraphiQL을 사용할 수 있습니다. GraphQL Playground를 사용하여 다음과 같은 Subscription 쿼리를 실행할 수 있습니다:

subscription {
messageAdded {
id
content
timestamp
}
}

이 쿼리를 통해 서버에서 발생하는 messageAdded 이벤트를 실시간으로 받을 수 있습니다.

에러 처리 및 해결 방법

  1. 에러: WebSocket connection failed

원인: WebSocket 서버가 제대로 설정되지 않았거나, 클라이언트가 서버와의 연결에 실패한 경우입니다.

해결 방법: WebSocket이 올바르게 설정되었는지 확인하고, 서버 로그에서 에러 메시지를 확인하여 원인을 파악합니다. WebSocket URL이 정확한지 확인하고, 네트워크 문제가 없는지 점검합니다.

  1. 에러: Subscription is not defined

원인: GraphQL 스키마에 정의된 Subscription 타입이 서버에 올바르게 로드되지 않았습니다.

해결 방법: 스키마 파일이 src/main/resources 디렉토리에 있는지 확인하고, 스키마 정의가 올바른지 검토합니다. 서버를 재시작하여 변경 사항이 적용되었는지 확인합니다.

  1. 에러: Cannot resolve field 'messageAdded'

원인: GraphQL Resolver에서 Subscription을 처리하는 메서드가 잘못 정의되었거나, Resolver가 Spring 컨텍스트에 등록되지 않았습니다.

해결 방법: Resolver 클래스가 @Component로 주입되어 있는지 확인하고, Subscription 메서드 이름이 스키마와 일치하는지 검토합니다.

참고문서

위의 문서들은 Spring Boot와 GraphQL Subscription을 설정하고 문제를 해결하는 데 유용한 자료를 제공합니다.

728x90
반응형