kagamihogeの日記

kagamihogeの日記です。

Spring for GraphQLのチュートリアルレベルをやる

Spring for GraphQLチュートリアルレベルの事をやる。

やったこと

hello world相当

https://start.spring.io/ でgraphql, webの依存性を追加する。build.gradleは下記となる。

plugins {
    id 'org.springframework.boot' version '2.7.0'
    id 'io.spring.dependency-management' version '1.0.11.RELEASE'
    id 'java'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '17'

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-graphql'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework:spring-webflux'
    testImplementation 'org.springframework.graphql:spring-graphql-test'
}

tasks.named('test') {
    useJUnitPlatform()
}

src/main/resources/application.propertiesに以下を任意で追加する。GraphQLはクライアントが必要だがこのプロパティによりブラウザでGraphQLを試せる。

spring.graphql.graphiql.enabled true

GraphQLのスキーマを追加する。デフォルトではsrc/main/resources/graphql/**.graphqls.gqlsの拡張子でスキーマファイルを作るので、src/main/resources/graphql/schema.graphqlsを作成する。スキーマの中身は https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web.graphql.schema をまずはコピペする。

type Query {
    greeting(name: String! = "Spring"): String!
    project(slug: ID!): Project
}

""" A Project in the Spring portfolio """
type Project {
    """ Unique string id used in URLs """
    slug: ID!
    """ Project name """
    name: String!
    """ URL of the git repository """
    repositoryUrl: String!
    """ Current support status """
    status: ProjectStatus!
}

enum ProjectStatus {
    """ Actively supported by the Spring team """
    ACTIVE
    """ Supported by the community """
    COMMUNITY
    """ Prototype, not officially supported yet  """
    INCUBATING
    """ Project being retired, in maintenance mode """
    ATTIC
    """ End-Of-Lifed """
    EOL
}

まずはgreetingのQueryを作る。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.graphql.data.method.annotation.Argument;
import org.springframework.graphql.data.method.annotation.QueryMapping;
import org.springframework.stereotype.Controller;

@Controller
@SpringBootApplication
public class BootGraphqlApplication {
  public static void main(String[] args) {
    SpringApplication.run(BootGraphqlApplication.class, args);
  }

  @QueryMapping
  public String greeting(@Argument String name) {
    return "Hello, " + name + "!";
  }
}

これを起動して http://localhost:8080/graphiql にアクセスする。下記のようなqueryを書いて実行すると結果が返ってくる。

query {
  greeting(name:"aaaaaaaabbbb")
}

次にprojectのQueryを作る。ProjectProjectStatusを作り、

public record Project(String slug, String name, String repositoryUrl, ProjectStatus status) {
}
public enum ProjectStatus {
  ACTIVE, COMMUNITY, INCUBATING, ATTIC, EOL
}

projectのQueryの本体はこんな感じ。

  @QueryMapping
  public Project project(@Argument String slug) {
    return new Project(slug, "asdf", "sadf", ProjectStatus.ACTIVE);
  }

http://localhost:8080/graphiql にアクセスしてqueryを実行すると以下のようになる。name, statusのみ指定してるのでそのフィールドしか返ってきてないのが分かる。

query {
  greeting(name:"testeset")
  
  project(slug:"hatenatena") {
    name,
    status
  }
}

Spring MVC以外で公開

上記はSpring MVCを使用したが、GraqhQLはそれらとは独立している。https://docs.spring.io/spring-boot/docs/current/reference/html/web.html#web.graphql.schema によると、下記が挙げられている。

  • spring-boot-starter-web
  • spring-boot-starter-websocket
  • spring-boot-starter-webflux
  • spring-boot-starter-rsocket

webfluxを試す。依存性にgraphql, webfluxを追加したものに変更する。

dependencies {
  implementation 'org.springframework.boot:spring-boot-starter-graphql'
  implementation 'org.springframework.boot:spring-boot-starter-webflux'
  developmentOnly 'org.springframework.boot:spring-boot-devtools'
  testImplementation 'org.springframework.boot:spring-boot-starter-test'
  testImplementation 'io.projectreactor:reactor-test'
  testImplementation 'org.springframework.graphql:spring-graphql-test'
}

とりあえずMonoを返すようにgreetingを修正する。

  @QueryMapping
  public Mono<String> greeting(@Argument String name) {
    return Mono.fromCallable(() -> "Hello, " + name + "!");
  }

あとは特に変わらず http://localhost:8080/graphiql からアクセスできる。

PostmanをGraqhQLクライアントとして使用

PostmanをGraqhQLクライアントとして使用する。

GraphQLのエンドポイントに POST http://localhost:8080/graphql注意 graphiqlではない)にアクセスする。BodyにGraphQLを選択してRefreshアイコンをクリックすれば後の使い勝手はgraphiqlと似たような感じ。

参照ドキュメント