[kotlin] 코틀린 웹 서버에서 GraphQL 서비스 개발 방법

GraphQL은 API를 위한 쿼리 언어이자 런타임입니다. 이는 클라이언트가 필요로 하는 데이터를 정확하게 요청할 수 있도록 도와줍니다. 이번 튜토리얼에서는 코틀린을 사용하여 웹 서버에서 GraphQL 서비스를 개발하는 방법에 대해 알아보겠습니다.

1. 프로젝트 설정

먼저, 코틀린 웹 서버를 위한 프로젝트를 설정해야 합니다. 이는 Gradle이나 Maven을 통해 진행할 수 있습니다.

Gradle:

plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.5.21'
    id 'org.jetbrains.kotlin.plugin.spring' version '1.5.21'
    id 'org.springframework.boot' version '2.5.4'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
java.sourceCompatibility = JavaVersion.VERSION_1_8

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'com.graphql-java:graphql-spring-boot-starter:15.0.0'
    implementation 'org.jetbrains.kotlin:kotlin-reflect'
    implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

Maven:

<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>graphql-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.graphql-java</groupId>
            <artifactId>graphql-spring-boot-starter</artifactId>
            <version>15.0.0</version>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-reflect</artifactId>
        </dependency>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-stdlib-jdk8</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
                <executions>
                    <execution>
                        <id>compile</id>
                        <goals>
                            <goal>compile</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>src/main/kotlin</sourceDir>
                                <sourceDir>src/main/java</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                    <execution>
                        <id>test-compile</id>
                        <goals>
                            <goal>test-compile</goal>
                        </goals>
                        <configuration>
                            <sourceDirs>
                                <sourceDir>src/test/kotlin</sourceDir>
                                <sourceDir>src/test/java</sourceDir>
                            </sourceDirs>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2. GraphQL 스키마 정의

GraphQL 스키마는 GraphQL API의 타입과 쿼리를 정의하는데 사용됩니다. 스키마를 작성하기 위해 .graphqls 또는 .graphql 파일을 생성하고 필요한 타입과 필드를 정의합니다.

예를 들어, Book 타입과 Query 타입을 갖는 schema.graphqls 파일을 작성해봅시다.

type Book {
  id: ID!
  title: String!
  author: String!
  publishedAt: String!
}

type Query {
  getAllBooks: [Book!]!
  getBookById(id: ID!): Book
}

3. GraphQL 서비스 구현

이제 GraphQL 서비스를 구현해보겠습니다. 코틀린에서는 스프링 부트와 함께 graphql-spring-boot-starter를 사용하여 쉽게 GraphQL 서비스를 생성할 수 있습니다.

@SpringBootApplication
class GraphqlServerApplication

fun main(args: Array<String>) {
    runApplication<GraphqlServerApplication>(*args)
}

@Configuration
class GraphqlConfiguration {

    @Bean
    fun graphQLSchema(): GraphQLSchema {
        val typeDefinitionRegistry = SchemaParser().parse(graphQlSchemaFile().inputStream())
        val runtimeWiring = buildRuntimeWiring()
        val schemaGenerator = SchemaGenerator()

        return schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring)
    }

    @Bean
    fun graphQlSchemaFile(): Resource {
        return ClassPathResource("schema.graphqls")
    }

    private fun buildRuntimeWiring(): RuntimeWiring {
        return RuntimeWiring.newRuntimeWiring()
            .type("Query") { builder ->
                builder.dataFetcher("getAllBooks", AllBooksDataFetcher())
                builder.dataFetcher("getBookById", BookByIdDataFetcher())
            }
            .build()
    }
}

@Component
class AllBooksDataFetcher : DataFetcher<List<Book>> {
    override fun get(environment: DataFetchingEnvironment): List<Book> {
        // 모든 책을 가져오는 로직 작성
        return listOf(/* Books */)
    }
}

@Component
class BookByIdDataFetcher : DataFetcher<Book> {
    override fun get(environment: DataFetchingEnvironment): Book {
        // ID로 특정 책을 가져오는 로직 작성
        val id = environment.arguments["id"] as String
        return /* Book */
    }
}

data class Book(val id: String, val title: String, val author: String, val publishedAt: String)

위의 코드는 GraphQL 서비스를 생성하기 위해 필요한 구성 코드입니다. GraphqlConfiguration 클래스에서는 스키마 파일을 로드하고, RuntimeWiring을 생성하여 쿼리를 처리할 데이터 페처를 지정합니다.

AllBooksDataFetcherBookByIdDataFetcher 클래스는 실제 데이터베이스에서 데이터를 가져오는 로직을 작성하면 됩니다.

4. 실행 및 테스트

이제 프로젝트를 빌드하고 실행해보겠습니다. 콘솔에서 다음과 같은 커맨드를 입력합니다:

./gradlew bootRun

GraphQL Playground 또는 다른 GraphQL 클라이언트 도구를 사용하여 GraphQL API를 테스트할 수 있습니다.

이상으로, 코틀린 웹 서버에서 GraphQL 서비스를 개발하는 방법을 알아보았습니다. GraphQL은 클라이언트와 서버 사이의 효율적인 데이터 통신을 도와주는 강력한 도구이므로 적절히 활용하면 많은 이점을 얻을 수 있습니다.

참고 자료