Skip to content

backpaper0/spring-graphql-introduction

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

77 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Spring GraphQL introduction

CI for example code

概要

JSUG勉強会 2021年その2 Spring GraphQLをとことん語る夕べでの発表のスライドとコード例です。 発表時はSpring GraphQL 1.0.0-M1でしたがM2、M3とバージョンを重ねているためたまにスライドを更新しています。 JSUGでの発表当時のスライドは20210806-jsugタグを参照してください。

資料のビルド

PlantUMLで描いた図をビルドする。

java -jar ~/plantuml.jar -tsvg docs/plantuml.pu

スライドをビルドする。

npx @marp-team/marp-cli@latest --html --output docs/index.html docs/slide.md

/docsをGitHub Pagesでホスティングするように設定しているので次のURLでスライドが見られる。

デモの手順

準備

./mvnw spring-boot:run

ブラウザで http://localhost:8080/graphiql を開く。

query操作

スライドにもあったクエリーを試す。

query {
  article(id: 1) {
    id
    title
    content
    category {
      id
      name
    }
  }
}

タイトルだけ取得するようにしてみる。

query {
  article(id: 1) {
    title
  }
}

変数を使ってみる。

query GetArticle($id: ID!) {
  article(id: $id) {
    title
  }
}
{
  "id": 1
}

curlでも試してみる。

curl -s http://localhost:8080/graphql -H "Content-Type: application/json" -d '{"query": "{article(id: 1) { id, title, content, category { id, name } }}"}' | jq

subscription

subscription操作も試してみる。

subscription {
  count
}

結果のエリアにカウントアップされて1から10まで表示される。

wscatでも確認してみる。 wscatnpm install -g wscatでインストールできる。

wscat --connect ws://localhost:8080/graphql

subscriptionのプロトコルはまだ理解していないので、Spring GraphQLのコードを読んでわかった手順を実施する。

まずはconnection_initが必要。

{"type": "connection_init"}

それからsubscribe。 待っていると1秒おきにカウントアップする値が返される。

{"type": "subscribe", "id": "...", "payload": {"query": "subscription { count }"}}

もちろん変数も使える。

{"type": "subscribe", "id": "...", "payload": {"query": "subscription Count($size: Int!) { count(size: $size) }", "variables": {"size": 5 }}}

DataLoader

まずはN + 1。

query {
  comics {
    title
    publisher {
      name
    }
  }
}

Fetch Query.comics以降のログを見るとcomicsで1回、comics.publisherで10回のクエリーが発行されていることがわかる。

次にDataLoader版。

query {
  comics {
    title
    author {
      name
    }
  }
}

Fetch Query.comics以降のログを見るとcomicscomics.authorが共に1回ずつのクエリー発行で済んでいることがわかる。

ページング

まずはafterを指定せずクエリーーを発行して返ってくる値を確認する。

query GitCommits {
  history {
    forward(first: 3) {
      edges {
        node {
          hash
          message
        }
        cursor
      }
      pageInfo {
        hasPreviousPage
        hasNextPage
        startCursor
        endCursor
      }
    }
  }
}

それからpageInfoの値を見ながらafterを設定しつつクエリーを試す。

query GitCommits {
  history {
    forward(first: 3, after: "3") {
      edges {
        node {
          hash
          message
        }
        cursor
      }
      pageInfo {
        hasPreviousPage
        hasNextPage
        startCursor
        endCursor
      }
    }
  }
}

後方も試す。

query GitCommits {
  history {
    backward(last: 3, before: "7") {
      edges {
        node {
          hash
          message
        }
        cursor
      }
      pageInfo {
        hasPreviousPage
        hasNextPage
        startCursor
        endCursor
      }
    }
  }
}

WIP: 認証・認可

次のクエリーを実行するとエラー(Unauthorized)になる。

{
  security {
    protected
  }
}

REQUEST HEADERSという場所に次のJSONを書いて実行するとエラーにならず値が返ってくる。

{
  "Authorization": "Basic ZGVtbzpzZWNyZXQ="
}

これは該当のDataFetcher内で呼び出されているコンポーネントのメソッドに@PreAuthorize("isAuthenticated()")を付けている。

カスタムdirectiveで認証を表現した例も作ってみた。 次のクエリーが@authenticatedというカスタムdirectiveで保護したフィールドへのアクセスとなる。

{
  security {
    protected2
  }
}

Authorizationヘッダーの有無による違いを試してみてほしい。

メトリクス

curl -s localhost:8080/actuator/metrics/graphql.request | jq
curl -s localhost:8080/actuator/metrics/graphql.datafetcher | jq
curl -s localhost:8080/actuator/metrics/graphql.error | jq

その他の話題

graphqlvizを使うとGraphQLスキーマを図にできる。

npx graphqlviz http://localhost:8080/graphql | dot -Tpng -o graphql-schema.png

次のような図が生成される。


ライセンス

スライド(docs/配下にあるファイル)はCC BY 4.0、ソースコード(スライド以外のファイル)はMITを適用します。

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

No packages published