GraphQL
基本用語
ミューテーション
データを変更する。 アプリケーションの状態を変更するために作成する。 ミューテーションはアプリケーションで使われる動詞と対応するのが望ましい。 サービスに対してできることがミューテーションとして定義される。
type Mutation { postPhoto( name: String! description: String category: PhotoCategory=PORTRAIT ): Photo! } schema { query: Query mutation: Mutation }
mutation { postPhoto(name: "Sending the Palisades") { id url created postedBy { name } } }
フラグメント
フラグメントは複数の場所で使いまわすことができる選択セット。
query { allTrails { ...trailStatus ...trailDetails } }
クエリ変数
クエリ内の静的な値を置き換えて動的な値を渡せる。
サブスクリプション
サーバを更新するたびにクライアントで情報をリアルタイムに受け取る。
subscription { liftStatusChange { name capacity status } }
{ “data”: { “liftStatusChange”: null } }
mutation closeLift { setLiftStatus(id: "astra-express" status: HOLD) { name status } }
{ “data”: { “setLiftStatus”: { “name”: “Astra Express”, “status”: “HOLD” } } }
変更内容がサブスクリプションしているクライアントに向けてプッシュされる。
イントロスペクション
APIスキーマの詳細を取得できる機能。
query { __schema { types { name description } } }
{ “data”: { “__schema”: { “types”: [ { “name”: “Lift”, “description”: “A `Lift` is a chairlift, gondola, tram, funicular, pulley, rope tow, or other means of ascending a mountain.” }, { “name”: “ID”, “description”: “The `ID` scalar type represents a unique identifier, often used to refetch an object or as key for a cache. The ID type appears in a JSON response as a String; however, it is not intended to be human-readable. When expected as an input type, any string (such as `\”4\“`) or integer (such as `4`) input value will be accepted as an ID.” }, { “name”: “String”, “description”: “The `String` scalar type represents textual data, represented as UTF-8 character sequences. The String type is most often used by GraphQL to represent free-form human-readable text.” }, { “name”: “Int”, “description”: “The `Int` scalar type represents non-fractional signed whole numeric values. Int can represent values between -(2^31) and 2^31 - 1.” }, { “name”: “Boolean”, “description”: “The `Boolean` scalar type represents `true` or `false`.” }, { “name”: “Trail”, “description”: “A `Trail` is a run at a ski resort” }, { “name”: “LiftStatus”, “description”: “An enum describing the options for `LiftStatus`: `OPEN`, `CLOSED`, `HOLD`” }, { “name”: “TrailStatus”, “description”: “An enum describing the options for `TrailStatus`: `OPEN`, `CLOSED`” }, { “name”: “SearchResult”, “description”: “This union type returns one of two types: a `Lift` or a `Trail`. When we search for a letter, we’ll return a list of either `Lift` or `Trail` objects.” }, { “name”: “Query”, “description”: null }, { “name”: “Mutation”, “description”: null }, { “name”: “Subscription”, “description”: null }, { “name”: “CacheControlScope”, “description”: null }, { “name”: “Upload”, “description”: “The `Upload` scalar type represents a file upload.” }, { “name”: “__Schema”, “description”: “A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.” }, { “name”: “__Type”, “description”: “The fundamental unit of any GraphQL Schema is the type. There are many kinds of types in GraphQL as represented by the `__TypeKind` enum.\n\nDepending on the kind of a type, certain fields describe information about that type. Scalar types provide no information beyond a name, description and optional `specifiedByUrl`, while Enum types provide their values. Object and Interface types provide the fields they describe. Abstract types, Union and Interface, provide the Object types possible at runtime. List and NonNull types compose other types.” }, { “name”: “__TypeKind”, “description”: “An enum describing what kind of type a given `__Type` is.” }, { “name”: “__Field”, “description”: “Object and Interface types are described by a list of Fields, each of which has a name, potentially a list of arguments, and a return type.” }, { “name”: “__InputValue”, “description”: “Arguments provided to Fields or Directives and the input fields of an InputObject are represented as Input Values which describe their type and optionally a default value.” }, { “name”: “__EnumValue”, “description”: “One possible value for a given Enum. Enum values are unique values, not a placeholder for a string or numeric value. However an Enum value is returned in a JSON response as a string.” }, { “name”: “__Directive”, “description”: “A Directive provides a way to describe alternate runtime execution and type validation behavior in a GraphQL document.\n\nIn some cases, you need to provide options to alter GraphQL’s execution behavior in ways field arguments will not suffice, such as conditionally including or skipping a field. Directives provide this by describing additional information to the executor.” }, { “name”: “__DirectiveLocation”, “description”: “A Directive can be adjacent to many parts of the GraphQL language, a __DirectiveLocation describes one such possible adjacencies.” } ] } } }
query liftDetails { __type(name: "Lift") { name fields { name description type { name } } } }
{ “data”: { “__type”: { “name”: “Lift”, “fields”: [ { “name”: “id”, “description”: “The unique identifier for a `Lift` (id: \”panorama\“)”, “type”: { “name”: null } }, { “name”: “name”, “description”: “The name of a `Lift`”, “type”: { “name”: null } }, { “name”: “status”, “description”: “The current status for a `Lift`: `OPEN`, `CLOSED`, `HOLD`”, “type”: { “name”: “LiftStatus” } }, { “name”: “capacity”, “description”: “The number of people that a `Lift` can hold”, “type”: { “name”: null } }, { “name”: “night”, “description”: “A boolean describing whether a `Lift` is open for night skiing”, “type”: { “name”: null } }, { “name”: “elevationGain”, “description”: “The number of feet in elevation that a `Lift` ascends”, “type”: { “name”: null } }, { “name”: “trailAccess”, “description”: “A list of trails that this `Lift` serves”, “type”: { “name”: null } } ] } } }
スキーマ
GraphQLによって、APIは型の集合としてとらえられるようになる。 データ型の集合をスキーマという。
ユニオン型・インターフェース型
異なる型が混在するフィールドを表現するのに使う。 含まれている複数の型がまったく異なるものであればユニオン型を、共通のフィールドがある場合はインターフェースを利用するのが一般的。
ドキュメント
""" 最低一度は認可されたユーザ """ type User { """ ユーザの一意のGitHubログインID """ githubLogin: ID! """ ユーザの姓名 """ name: String """ このユーザが投稿した全写真 """ postedPhotos: [Photo!]! """ このユーザが含まれる全写真 """ inPhotos: [Photo!]! } type Mutation { """ GitHubユーザで認可 """ githubAuth( "ユーザの認可のために送信されるGitHubの一意のコード" code: String! ): AuthPayload! }
Emacs設定
Emacsでコード、クエリアクセス、結果出力をプレーンテキストで残す設定。
graphql-modeを追加する。 davazp/graphql-mode: An Emacs mode for GraphQL
ob-graphqlを追加する。 jdormit/ob-graphql: GraphQL execution backend for org-babel
取得元を入力#+BEGIN_SRCに入れることで、org-babelでクエリを実行できる。
query GetContinents { continent(code: "AF") { name code } }
{ “data”: { “continent”: { “name”: “Africa”, “code”: “AF” } } }
Tasks
TODO 雑に始める GraphQL Ruby【class-based API】 - Qiita
RubyでGraphQLを使う方法。
TODO Reading: 初めてGraphQL - 型の基礎|tkhm|note
graphqlの記事。
Reference
GraphQL - Guides Index
ドキュメント。
graphql/graphql-playground: 🎮 GraphQL IDE for better development workflows (GraphQL Subscriptions, interactive docs & collaboration)
graphqlのサンプル。
graphql/graphiql: GraphiQL & the GraphQL LSP Reference Ecosystem for building browser & IDE tools.
graphqlのサンプル。
Explorer - GitHub Docs
GitHubのGraphQL API。
A Gentle Introduction To Graph Theory - DEV Community
ノードとエッジについてのブログ記事。
SWAPI GraphQL API
サンプルでどんな感じかテストできるサイト。 スターウォーズの情報にアクセスできる。
query { person(personID: 5){ name birthYear created filmConnection { films { title } } } }
null
Archives
DONE 初めてのGraphQL ―Webサービスを作って学ぶ新世代API
- 86, 100, 124, 147, 185, 190, 197, 229
実際にコードとして書いていくのにはあまり評判がよくない。概要を知るためには役立つよう。 コードサンプルはJavaScript, node.js, expressなので、元からこれらについて知らないとあまりピンとこない感じがする。
メモ。 グラフ理論。グラフは概念同士の関係性を図示するための優れた考え方。 SQLはデータベースのための問い合わせ言語で、GraphQLはインターネットのための問い合わせ言語。