LoginSignup
11
2

More than 1 year has passed since last update.

【初心者向け】GraphQLで国を知るドリル

Last updated at Posted at 2021-12-15

おはこんばんちは、海外旅行に行きたいちーずです。

GraphQLを「超なんとなく」で使っていたため、基本文法まとめようと思ったら
いつの間にかクイズになってました。
GraphQLをはじめてみたい!という人はぜひチャレンジしてみてください!!

ルール

今回のクイズでは、publicで公開されている「国API」を使って、

  • schemaの読み方
  • GraphQLの基本的なクエリの書き方

を学んでいきます。

このAPIでは、大陸 - continent / 国 - country / 言語 - language の取得ができます。

▼ 今回使う国APIのgithub

下記のplaygroundを使って、実際にクエリを実行してみて答えに辿り着けるかチャレンジしてみてください!

▼ playground

schema (クリックすると見れるよ)
schema.graphql
directive @cacheControl(
  maxAge: Int
  scope: CacheControlScope
) on FIELD_DEFINITION | OBJECT | INTERFACE
enum CacheControlScope {
  PUBLIC
  PRIVATE
}

type Continent {
  code: ID!
  name: String!
  countries: [Country!]!
}

input ContinentFilterInput {
  code: StringQueryOperatorInput
}

type Country {
  code: ID!
  name: String!
  native: String!
  phone: String!
  continent: Continent!
  capital: String
  currency: String
  languages: [Language!]!
  emoji: String!
  emojiU: String!
  states: [State!]!
}

input CountryFilterInput {
  code: StringQueryOperatorInput
  currency: StringQueryOperatorInput
  continent: StringQueryOperatorInput
}

type Language {
  code: ID!
  name: String
  native: String
  rtl: Boolean!
}

input LanguageFilterInput {
  code: StringQueryOperatorInput
}

type Query {
  continents(filter: ContinentFilterInput): [Continent!]!
  continent(code: ID!): Continent
  countries(filter: CountryFilterInput): [Country!]!
  country(code: ID!): Country
  languages(filter: LanguageFilterInput): [Language!]!
  language(code: ID!): Language
}

type State {
  code: String
  name: String!
  country: Country!
}

input StringQueryOperatorInput {
  eq: String
  ne: String
  in: [String]
  nin: [String]
  regex: String
  glob: String
}

scalar Upload

第一問: 世界のすべての大陸名を答えよ

答え

アジア大陸 / ヨーロッパ大陸 / アフリカ大陸 / オーストラリア大陸 / 北アメリカ大陸 / 南アメリカ大陸 / 南極大陸 の七つでした!!

ちなみに大陸の分け方は諸説あるみたいです。
日本の社会の授業では「六大陸」だったような...?

https://fundo.jp/326717

query {
  continents {
    name
  }
}

解説: schemaの基本的な型 / queryの書き方

schemaの見方

1. ルート型を見つける

ルート型には、下記の3種類があります。

  • Query - データの取得 (get)
  • Mutation - データの追加/更新/削除 (post)
  • Subscription - データ更新の監視

ルートクエリ型は、schemaにて定義しなおすこともできます。

schema {
  query: query_root
  mutation: mutation_root
  subscription: subscription_root
}

今回は「データの取得」をしたいため、「type Query」を探します。

type Query {
  continents(filter: ContinentFilterInput): [Continent!]!
  continent(code: ID!): Continent
  countries(filter: CountryFilterInput): [Country!]!
  country(code: ID!): Country
  languages(filter: LanguageFilterInput): [Language!]!
  language(code: ID!): Language
}

これが、叩けるクエリです。

2. フィールドの型

GraphQLのschemaのフィールドには大きく分けてスカラー型オブジェクト型があります。

スカラー型
String  :文字列型
Int     :整数型
Float   :浮動小数点型
Boolean :論理型(true / false)
ID      :ID型(ユニークな文字列)
オブジェクト型

フィールドの集合体をオブジェクト型と言います。
下記のように、定義したtypeをそのまま使います。

type User {
  code: ID!
  name: String
}

Query {
  user: User // これがオブジェクト型
}

! is 何

type User {
  code: ID!
  name: String
}

このように、型の後ろに!があるケースがありますが、
これは「nullを許容しない」ことを意味します。

クエリの書き方

query{} の中にフィールドを列挙していくだけです。
queryごとにDBへのお問い合わせがいくため、なるべくqueryは分割しないほうが良いです。

query {
  フィールド名 
}

第二問: カナダの首都は?

ヒント: カナダのcodeはCAです

答え

「Ottawa(オタワ)」でした!
バンクーバーじゃないんですね!!笑

query {
  country(code: "CA") {
    capital
  }
}

解説: 引数 / input に関して

引数 / input

引数としてフィールドに渡す時は、typeではなくinputで定義します。

input UserInput {
  code: ID!
}

query {
  user(code: UserInput): [User!]!
}

第三問: ポンド(GBP)を使われている国は?

答え
  • イギリス(United Kingdom)
  • ガーンジー島(Guernsey)
  • サウスジョージア・サウスサンドウィッチ諸島(South Georgia and the South Sandwich Islands)
  • マン島(Isle of Man)
  • ジャージー島(Jersey)

案外あるんや!!と思ったのですが、ほぼほぼイギリス周りの島国です

query {
  countries (filter: {currency: {eq: "GBP"}}) {
    name
  }
}

第三問の拡張なので、説明は割愛させていただきます。

第四問: 日本とアメリカの「名前」「絵文字」「大陸名」は?

ヒント: 日本のcodeはJP / アメリカのコードはUS

答え

:flag_jp: :flag_us:
fragment details on Country {
  name
  emoji
  ctinent {
    name
  }
}

query {
  Japan: country(code: "JP") {
    ...details
  }
  America: country(code: "US") {
    ...details
  }
}

解説: フラグメント / エイリアス

フラグメント

複数回登場するコードをフラグメントでまとめることができます。

書き方は typeではなくfragment on 継承元のように書いて、
呼び出す時は {...fragment}と書きます。
オブジェクトのスプレッド演算子みたいですね!!

エイリアス

オブジェクトのキーみたいに書くと、エイリアスを切ることができます。
データの取得時にアクセスしやすいよう工夫するときに使います。


参考

11
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
2