DEV Community

kaede
kaede

Posted on

GraphQL で StarWars API の planets にネストされた films をとってくる

何がしたいのか

Star Wars API を使って

GraphQL で複数のテーブルが関連したデータを取ってくる練習がしたかった。

appPlanets というエンドポイント?を叩いた。

https://www.back4app.com/database/davimacedo/swapi-star-wars-api/graphql-playground/all-planets

Chrome でアクセスするだけで実行できる
Back4App というところを使った。

https://github.com/graphql/swapi-graphql/blob/7c02fdf5244d8ca66005b9707f634b94364f31c1/schema.graphql#L483

定義はこの公式のスキーマの 483 行目から。


Root -> allPlanets

type Root { allFilms(after: String, first: Int, before: String, last: Int): FilmsConnection film(id: ID, filmID: ID): Film allPlanets(after: String, first: Int, before: String, last: Int): PlanetsConnection planet(id: ID, planetID: ID): Planet node( """The ID of an object""" id: ID! ): Node } 
Enter fullscreen mode Exit fullscreen mode

Root に AllPlanets が結び付けられている。
そしてそれが PlanetsConnection で Planet を参照しているようだ。


PlannetsConnection -> Planet

type PlanetsConnection { totalCount: Int planets: [Planet] } 
Enter fullscreen mode Exit fullscreen mode

PlannetsConnection の定義のコードを見ると
planets として Planet の配列が参照されている。

なので今回は planets をエンドポイントとして叩く。


Planet

単体の Planet の定義もみてみる。

type Planet implements Node { """The name of this planet.""" name: String gravity: String created: String id: ID! } 
Enter fullscreen mode Exit fullscreen mode
  • name
  • gravity
  • created
  • id

これらの順番で中身が並べられている。


Back4App で planets の GET を実行する

https://www.back4app.com/database/davimacedo/swapi-star-wars-api/graphql-playground/all-planets

Back4App なら Star Wars API の
リポジトリを clone して npm start しなくても
URL を開くだけで実行できる。

query allPlanets { planets (skip: 0, limit: 3) { results { id, name, gravity, createdAt, } } } 
Enter fullscreen mode Exit fullscreen mode

allPlanets という名前(ここは自由)で定義して
planets を叩く。

skip は 0 で最初のひとつめから、
limit は 3 で 3 つだけ

JS の関数の戻り値と似た感じで、
返す値は results で定義するようだ。

呼び出す順番は自由。

{ "data": { "planets": { "results": [ { "id": "JNgiSeuJwR", "name": "Yavin IV", "gravity": "1 standard", "createdAt": "2019-12-13T19:42:31.014Z" }, { "id": "lZHyO0MIr6", "name": "Dagobah", "gravity": null, "createdAt": "2019-12-13T19:42:31.017Z" }, { "id": "PL36fSGLoW", "name": "Tatooine", "gravity": "1 standard", "createdAt": "2019-12-13T19:42:30.901Z" } ] } } } 
Enter fullscreen mode Exit fullscreen mode

結果は json で返ってくる。
data/tableName/results に入っている。

skip を 1 にすると
最初の Yavin IV が skip されて
Alderaan が 3 つめに食い込んでくる。


filmConnection で Planet に結びつく Film も GET する

 filmConnection(after: String, first: Int, before: String, last: Int): PlanetFilmsConnection 
Enter fullscreen mode Exit fullscreen mode

Planet には Film とむすびつける
filmConnection というカラムもある。

これは PlanetFilmsConnection を使っていて

type PlanetFilmsConnection { pageInfo: PageInfo! totalCount: Int films: [Film] 
Enter fullscreen mode Exit fullscreen mode

このようになっている。

なので、films を追加すれば
惑星に関連するフィルムたちも取れるだろう。

type Film implements Node { title: String director: String releaseDate: String } 
Enter fullscreen mode Exit fullscreen mode

Film には
title, director, releaseDate,

これらの項目があったのでそれらをいれて

query allPlanets { planets (skip: 0, limit: 3) { results { id, name, gravity, createdAt, films { results { title, director, releaseDate } } } } } 
Enter fullscreen mode Exit fullscreen mode

planets にリクエスト項目を追加する。

 "createdAt": "2019-12-13T19:42:30.901Z", "films": { "results": [ { "title": "A New Hope", "director": "George Lucas", "releaseDate": "1977-05-25T00:00:00.000Z" }, { "title": "Attack of the Clones", "director": "George Lucas", "releaseDate": "2002-05-16T00:00:00.000Z" }, 
Enter fullscreen mode Exit fullscreen mode

すると、films の項目で
惑星データに関連する映画のタイトル、監督、公開日、これらが取れた。


まとめ

GraphQL をてっとり早く試すには

Back4App の Starwars API の
Planets と Films のデータが便利。

type Root { allPlanets(after: String, first: Int, before: String, last: Int): PlanetsConnection } 
Enter fullscreen mode Exit fullscreen mode

Root で allPlanets として PlanetsConnection
が結びついている。

なので allPanets というエンドポイントが発生すると推測する。

type PlanetsConnection { totalCount: Int planets: [Planet] } 
Enter fullscreen mode Exit fullscreen mode

PlanetsConnection が planets として
Planet たちの配列を取っている。

type Planet implements Node { name: String id: ID! } 
Enter fullscreen mode Exit fullscreen mode

そして Planet の内部に id や name などのカラムが入っている。

query allPlanets { planets (skip: 0, limit: 3) { results { id, name, 
Enter fullscreen mode Exit fullscreen mode

この形でリクエストする。results の中にカラムを書く。

 filmConnection(after: String, first: Int, before: String, last: Int): PlanetFilmsConnection 
Enter fullscreen mode Exit fullscreen mode

Planet の中にさらに filmConnection という
Planet と Films を結びつけるカラムがあり
PlanetFilmConnection を呼び出している

type PlanetFilmsConnection { pageInfo: PageInfo! totalCount: Int films: [Film] 
Enter fullscreen mode Exit fullscreen mode

PlanetFilmsConnection には films として
Film たちの配列が入っている。

これをリクエストするには、

query allPlanets { planets (skip: 0, limit: 3) { results { id, name films { results { title, director, releaseDate } 
Enter fullscreen mode Exit fullscreen mode

このように、results の films の更に results として
Film のカラムを書いてリクエストする。

以上。

Top comments (0)