1 of 38

RustのSchema First GraphQLライブラリrusty-gqlを作った話

Takuro Iwamoto

2 of 38

Introduction

・Tak-Iwamoto / 岩本卓朗

・webアプリケーションエンジニア

3 of 38

Outline

・RustとGraphQL

・rusty-gqlの紹介、デモ

・GraphQLライブラリの実装方法

4 of 38

RustとGraphQL

5 of 38

GraphQL

Rust

・APIのスキーマ、型の定義

・クライアントのクエリに基づいたAPIレスポンス

・メモリ効率、パフォーマンスに優れた言語

・リッチな型システム

6 of 38

GraphQL

Rust

・APIのスキーマ、型の定義

・クライアントのクエリに基づいたAPIレスポンス

・メモリ効率、パフォーマンスに優れた言語

・リッチな型システム

7 of 38

GraphQL

Rust

8 of 38

既存のRustのGraphQLライブラリ

・juniper

・async-graphql

・Code Firstのアプローチ

9 of 38

Code First vs Schema First

・Code First: コードでGraphQLのスキーマ定義と実装を行う

・Schema First: GraphQLでスキーマ定義した後にコードを生成

10 of 38

Code First vs Schema First

・Code First: コードでGraphQLのスキーマ定義と実装を行う

・Schema First: GraphQLでスキーマ定義した後にコードを生成

どちらが良いのか?

11 of 38

At Netflix we strongly prefer schema-first development.

・The schema design is front and center of the developer experience.

参照: Netflix Technology Blog: Open Sourcing the Netflix Domain Graph Service Framework: GraphQL For Spring Boot

Netflix製のGraphQLライブラリ

12 of 38

At Netflix we strongly prefer schema-first development.

・The schema design is front and center of the developer experience.

参照: Netflix Technology Blog: Open Sourcing the Netflix Domain Graph Service Framework: GraphQL For Spring Boot

Netflix製のGraphQLライブラリ

13 of 38

At Netflix we strongly prefer schema-first development.

・The schema design is front and center of the developer experience.

参照: Netflix Technology Blog: Open Sourcing the Netflix Domain Graph Service Framework: GraphQL For Spring Boot

Netflix製のGraphQLライブラリ

rusty-gqlはSchema Firstを採用

14 of 38

rusty-gql

15 of 38

rusty-gql

・Schema First

・Convention Over Configuration

・Code Generate from GraphQL schema

16 of 38

Getting Started

・CLIをinstallしてProject作成

17 of 38

GraphQLのスキーマ定義

・schema/** 配下に.graphqlファイルを定義

・rusty-gql generate(rusty-gql g)を実行

・関連ファイルが生成される

schema/schema.graphql

18 of 38

Resolverの実装

schema/schema.graphql

src/graphql/query/todos.rs

19 of 38

Demo

20 of 38

GraphQLライブラリの実装方法

21 of 38

GraphQLライブラリとは

・GraphQLライブラリ: GraphQLの仕様通りに処理を行うもの

22 of 38

GraphQLライブラリとは

GraphQLライブラリ: GraphQLの仕様通りに処理を行うもの

GraphQL処理系

23 of 38

GraphQLライブラリとは

GraphQLライブラリ: GraphQLの仕様通りに処理を行うもの

GraphQL処理系

言語処理系のプロセスと類似

24 of 38

GraphQL処理系の実装方法

  1. GraphQLリクエストをparseして抽象構文木(AST)に変換
  2. ASTからオブジェクトのFieldごとにResolverを実行
  3. 実行結果をserializeしてクライアントに返す

25 of 38

GraphQL処理系の実装方法

  • GraphQLリクエストをparseして抽象構文木(AST)に変換
  • ASTからオブジェクトのFieldごとにResolverを実行
  • 実行結果をserializeしてクライアントに返す

26 of 38

GraphQL AST

  • SelectionSet: 複数のFieldを持つ
  • Field:
    • オブジェクトのField
    • SelectionSetを持つ場合もある。

GraphQL Spec https://spec.graphql.org/October2021/

27 of 38

Parser

・github.com/graphql-rust/graphql-parser

28 of 38

GraphQL処理系の実装方法

  • GraphQLリクエストをparseして抽象構文木(AST)に変換
  • ASTからオブジェクトのFieldごとにResolverを実行
  • 実行結果をserializeしてクライアントに返す

29 of 38

Resolver

  • Fieldごとにどのような値を返すのか定義したメソッド
    • rusty-gqlではResolverとして非同期関数を定義
  • クエリにFieldが含まれているときのみ実行される

30 of 38

GraphQL

Rust

31 of 38

Queryは並列に実行

GraphQLクエリ

Rustの処理

※疑似コードです

32 of 38

GraphQL処理系の実装方法

  • GraphQLリクエストをparseして抽象構文木(AST)に変換
  • ASTからオブジェクトのFieldごとにResolverを実行
  • 実行結果をserializeしてクライアントに返す

33 of 38

Serdeを使用してSerialize

GraphQL

Rust

34 of 38

Serdeを使用してSerialize

GraphQL

Rust

どうやってGqlValueを

生成するのか?

35 of 38

FieldResolver trait

GqlValueを返すFieldResolver traitを定義

組み込みの型に対してもtraitをimplしている

36 of 38

proc-macroの活用

GraphQLの型にはproc-macroでFieldResolverをimplする

37 of 38

Summary

・RustとGraphQLは型定義が柔軟にできる点で相性が良い

・Schema FirstなGraphQLライブラリrusty-gqlを作った

・rusty-gqlは並列処理、proc-macroなどRustの機能を最大限

利用して実装している

38 of 38

Thank you for watching!