AWS AppSyncを始めるにあたり、まずはGraphQLをキャッチアップする必要があったので記事に起こしてみました。
graphql.orgのイントロから、GraphQLを始めるための情報をピックアップします。
足りない部分は今後追記予定。
はじめに
GraphQLとは。
- クエリ言語の言語仕様である
- クエリ言語を実行するサーバー側のランタイムも指す
特定のデータストアに結びつく技術ではない。
GraphQLをはじめるために
次の要素が必要。
- データフィールドと型の定義
- フィールドに対するデータアクセスの実装
type Query {
me: User
}
type User {
id: ID
name: String
}
データアクセスの実装は、上記の宣言とデータストアを結びつけるもの。GraphQL仕様とは独立した要素だが、必要。
// データアクセスの仮実装
function Query_me(request) {
return request.auth.user;
}
function User_name(user) {
return user.getName();
}
上記のような宣言(と実装)に対して、クライアントから me
というデータをクエリしてみる。
クエリの表現は下記のようになる。
{
me {
name
}
}
対するGraphQLサービスからのレスポンスの一例は、以下のようなjsonとなる。
{
"me": {
"name": "Luke Skywalker"
}
}
Queries and Mutations
クエリで「欲しいフィールド」を要求することで、GraphQLランタイムは要求されたデータ のみ を返す。クライアントにとって必要なデータだけが返るようになっている。ネストされているデータ構造でも有効。
Auguments
SQLにおける where
のようなことができる。以下のクエリでは、 id: "1000"
が相当する。
{
human(id: "1000") {
name
height
}
}
クエリの中で引数を宣言的に記述できるので、パッと見がわかりやすい。
また、 where
だけでなくちょっとした関数の適用のような芸当も可能。以下の例では、スカラータイプのフィールドである height
に対して、単位を変換して返すようリクエストを行っている。
{
human(id: "1000") {
name
height(unit: FOOT)
}
}
Aliases
引数のみ異なる複数のフィールドにリクエストをかけたい場合に利用する。
次の例では episode
の引数を変えた2つの hero
を取り出しており、それぞれに empireHero
jediHero
というエイリアスを張っている。
{
empireHero: hero(episode: EMPIRE) {
name
}
jediHero: hero(episode: JEDI) {
name
}
}
Fragments
要求するデータ構造で多少複雑なものが欲しくなった時に。
Exampleを見ていると、個人的にはCのインライン関数やマクロあたりに近いイメージを持った。fragmentを定義してクエリ中に宣言することで、その場所に展開される。
下記の例では ...comparisionFields
にfragmentsで宣言した構造を展開してリクエストを行う様を確認できる。
{
leftComparison: hero(episode: EMPIRE) {
...comparisonFields
}
rightComparison: hero(episode: JEDI) {
...comparisonFields
}
}
fragment comparisonFields on Character {
name
appearsIn
friends {
name
}
}
戻ってくるフィールドは leftComparison
と rightComparison
である。で、それぞれの中身は ...comparisionFields
の展開形、つまり fragment comparisonFields
の宣言内容に準じるものとなる。
{
"data": {
"leftComparison": {
"name": "Luke Skywalker",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
},
{
"name": "C-3PO"
},
{
"name": "R2-D2"
}
]
},
"rightComparison": {
"name": "R2-D2",
"appearsIn": [
"NEWHOPE",
"EMPIRE",
"JEDI"
],
"friends": [
{
"name": "Luke Skywalker"
},
{
"name": "Han Solo"
},
{
"name": "Leia Organa"
}
]
}
}
}
Operation name
読んで字の如くで、意図する「操作」を宣言するためのもの。 query
と mutation
subscription
の3種類ある。
query
に関しては省略記法も利用可能。ここまでのexampleがまさしくで、これらは暗黙的に query
を利用している。
query HeroNameAndFriends {
hero {
name
friends {
name
}
}
}
複数のOperationを含むクエリを記述する場合には必須となる。しかし、「操作」を明示的にクエリに含むことがサーバーサイドでのロギング観点で有用であるため、指定することが推奨される。
Variables
(追記予定)
Directives
(追記予定)
Mutations
(追記予定)
Inline Fragments
(追記予定)