GraphQL勉強会

 GraphQL勉強会

GraphQL + Go + React + Apolloでサンプルアプリ作ってみた

8df3fb7cd30531313d0df24d1ce09c1e?s=128

hideto_iwasawa

September 15, 2020
Tweet

Transcript

  1. GraphQL Atrae.Inc Hideto Iwasawa

  2. まずはGraphQLを入門... GraphQLって なんだ? GraphQLって なんだ? 何からすれば 良い?

  3. とりあえず公式サイトをみてみるか・・・ 公式サイト(https://graphql.org/)

  4. GraphQLってなんだ? 訳: API用のクエリ言語 GraphQLはAPI用のクエリ言語であり、 既存のデータを使ってクエリを実行する ためのランタイムです。 GraphQLは、 API内のデータを完全かつ理解しやすい 形で記述し、クライアントが必要とするも のだけを正確に要求できるようにしま

    す。さらにAPIを長期的に進化させること を容易にし、強力な開発者ツールを可 能にします。 special thanks to DeepL ふむふむ、よくわからん。 あるあるの展開だな。
  5. REST APIとの比較 https://www.webprofessional.jp/rest-2-0-graphql/

  6. 案ずるより産むが易し

  7. 例えば query response { me { name } } {

    “me”: { “name”: “hideto” } }
  8. 対象の返り値が複数ある時 query response { user { name friends { name

    } } } { “data”: { “user”: { “name”: “hideto” “friends”: [ { “name”: “kento” }, { “name”: “mako” }, { “name”: “onoda” } ] } } }
  9. 引数を渡してレスポンスを指定  query response { human(id: "1000") { name height }

    } { “data”: { “human”: { “name”: “hideto”, “height”: 1.76 } } }
  10. query response { human(id: "1000") { name height } }

    { “data”: { “human”: { “name”: “hideto”, “height”: 1.76 } } } 体重とか血液型、誕生日も 取ってこれるのかな? name: ‘hideto’ height: 1.76 weight: 70 blood type: ‘AB’ birthday: ‘10/15’ company: ‘Atrae.Inc’ address...
  11. schema type Human {
 id: ID!
 name: String!
 height(unit: LengthUnit

    = METER): Float
 blood_type: String!
 }
 体重は非公開なのか!
  12. 特徴 - queryとresponseの形が同じになる。 - 引数を用いてレスポンスを限定できる。 - 1つのエンドポイントでデータを取得できる - スキーマによってフロントとAPI側の共通認識が図りやすい

  13. 実装

  14. gqlgenを使って実装 $ mkdir graphql_sample $ cd graphql_sample $ go mod

    init graphql_sample $ go get -u github.com/99designs/gqlgen $ gqlgen init
  15. models_gen.go schema.graphqls

  16. resolver.go schema.resolvers.go 書き換え

  17. $ go run server.go http://localhost:8080

  18. next.jsとapolloを使ってfrontを実装

  19. $ yarn create next-app graphql_sample_front $ cd graphql_sample_front material-uiなどを使っ てまずはUIを

    実装!
  20. $ yarn add @apollo/client apolloを導入 apolloはGraphQLを使うことを前提につくられたライブラリーであり、クライアントとサーバーの間の通 信を簡単にしてくれる。 状態管理やキャッシュ機能も簡単に提供してくれる。 (Reduxの代わりになるという説も出ている。) apollo

    client, apollo server共にあるが、今回は apollo clientのみを使用する。
  21. _app.js import {ApolloClient, InMemoryCache, ApolloProvider} from "@apollo/client"; const client =

    new ApolloClient({ uri: 'http://localhost:8080/query', cache: new InMemoryCache() }); function MyApp({ Component, pageProps }) { return ( <ApolloProvider client={client}> <Component {...pageProps} /> </ApolloProvider> ) } ① ② ① GraphQLサーバーのURLを指定する。今回は localhostになっているが、本番デプロイやテスト環境 のことを考えると環境変数にすることが望ましい。 ② ComponentをこのApolloProviderで囲うことで各Componentの中で状態管理を行う useQuery, useMutationなどが使えるようになる。
  22. import {gql, useMutation, useQuery} from '@apollo/client'; import {useState} from "react";

    const FIND_TODOS = gql` query findTodos { todos { text done user { name } } } ` const ADD_TODO = gql` mutation createTodo($text: String!) { createTodo(input:{text: $text, userId:"1"}) { user { id } text done } } ` export default function Home() { const { loading, error, data, refetch } = useQuery(FIND_TODOS); const [addTodo] = useMutation(ADD_TODO) const [text, setText] = useState("") if (loading) return <p>Loading...</p>; if (error) return <p>Error :(</p>; const onClick = (e) => { addTodo({ variables: {text: text}} ) refetch() setText("") } return ( ... GraphQLサーバーに送るクエリを記述 FIND_TODOS: すでにあるTodoを全て取得 ADD_TODO: 新しいTodoを作成 useQueryの返り値であるloading, errorをみて画面を切り替えることが できる。refetchで改めて取得できるので、新しく Todoを追加した際に はrefetchする。 useMutationで新しくTodoを追加。
  23. None
  24. None
  25. まとめ・感想 ❏ エンドポイントを1つにして欲しい情報を取ってくるという方法は開発の工数やフロントとサーバーの通 信のやりとりという観点で利点があり、適する場面で RESTにかわり使う場面はありそう。 ❏ スキーマに基づいているため、より型安全な開発を行うことができる ❏ Apolloが状態管理までやってくれるためフロント開発で今後重宝される場面はありそう。 (実際にすごく推してる人もちらほら)

    ❏ フロント側の開発のしやすさは上がるものの、サーバー側できたリクエストを sqlに処理してデータ ベースへの負荷を小さくするという処理が大変である ❏ 本格的にRESTに変わるのは上記の問題を解決する信頼できるライブラリーの開発されてからではな いか。
  26. 参考文献 - https://employment.en-japan.com/engineerhub/entry/2018/12/26/103000#GraphQL%E3%81%AE%E3%82%B7%E3%83% B3%E3%83%97%E3%83%AB%E3%81%AA%E4%BE%8B - https://vitalify.jp/app-lab/20171006-graphql/ - https://future-architect.github.io/articles/20200609/ - https://qiita.com/SiragumoHuin/items/cc58f456bc43a1be41b4

    - https://www.webprofessional.jp/rest-2-0-graphql/