17
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Apollo+Expressで始めるGraphQL超入門 ~ データ取得Lv1

Last updated at Posted at 2019-04-11

あらすじ

1.Apollo+Expressで始めるGraphQL超入門 ~ GraphQLをざっくり理解する

はじめに

前回の続きをやっていきます。
そのため使用するソースや環境構築は あらすじ を参照してくだい。

今回はデータの取得について色々書いていこうと思います。

※ 筆者はまだまだ初心者です。間違った解釈や実装などがあればご指摘お願いします。

Select

GraphQLは、必要なときに必要なものを取得することできます。
いらないデータは指定しなければ取得されません。

type User {
  id: Int
  name: String
  age: Int
  created_date: String
}

Userに対して idname があればOKであればクエリにそう書きましょう。

{
  users {
    id
    name
  }
}

SQLのSELECTみたいな感じですね。

Limit

実装

app.js
const typeDefs = gql`
  type User {
    id: Int
    name: String
    age: Int
    created_date: String
  }
  type Query {
-   users: [User]
+   users(limit: Int): [User]
  }
`;

typeDefsQueryusers に対して引数を設定します。
limit は数字がくるように設定しました。

app.js
const resolvers = {
  Query: {
-   users: () => users
+   users: (parent, args) => {
+     let result = users;
+     let limit = args.limit || null;
+
+     if (limit) {
+       result = result.slice(0, limit);
+     }
+
+     return result
+   }
  }
};

resolversQuery に引数が渡るように設定しました。
args に引数が代入されます。
あとは、渡された limit の数字に沿って処理を行うだけです。

※ コードの書き足しを行ったらnodeタスクを再起動してください

実行

{
  users(limit: 3) {
    id
    name
  }
}
スクリーンショット 2019-04-11 17.06.27.png

Limit Done!

Sort

Users を年齢でソートかけてみましょう。

年齢の降順、昇順が行えるように設定します。

実装

app.js
const typeDefs = gql`
  type User {
    id: Int
    name: String
    age: Int
    created_date: String
  }
  type Query {
    users: [User]
-   users(limit: Int): [User]
+   users(limit: Int, age_sort:String): [User]
  }
`;

age_sort という引数を足しました。 String 型で DESC か、 ASC が指定される想定です。

app.js
const resolvers = {
  Query: {
   users: () => users
   users: (parent, args) => {
     let result = users;
     let limit = args.limit || null;
+    let age_sort = args.age_sort || "";
+
+    if (age_sort) {
+      const ope = age_sort === 'ASC' ? 1 : -1;
+      result = users.sort((x, y) => {
+        if (x['age'] > y['age']) return ope;
+        if (x['age'] < y['age']) return -(ope);
+        return 0;
+      })
+    }

     if (limit) {
       result = result.slice(0, limit);
     }

     return result
   }
  }
};

これで年齢ソートができるようになります。

しかし、age_sortの引数に DESC, ASC 以外の文字列が設定されたらどうでしょう。
正しく処理が行えなくなってしまいます。

そこで新しい概念として enum を使ってみましょう。

enum とは TypeScriptで例えるとわかりやすいのですが

age_sort: "DESC" | "ASC";

指定した文字列のみに制限することができます!

enumの場合だとこのような書き方となります。

enum SortOP {
  ASC
  DESC
}

指定したい文字列が決まっている場合は enum を使ったほうが圧倒的にわかりやすくメンテしやすいコードになりますので、
こちらを使うことをおすすめします。

それでは enum で実装し直してみます。

const typeDefs = gql`
  type User {
    id: Int
    name: String
    age: Int
    created_date: String
  }
+ enum SortOP {
+   ASC
+   DESC
+ }
  type Query {
-   users(limit: Int, age_sort:String): [User]
+   users(limit: Int, age_sort:SortOP): [User]
  }
`;

これで age_sort には ASC, DESC が設定されるように型定義しました。

実行

{
  users(age_sort: DESC) {
    name
    age
  }
}
スクリーンショット 2019-04-11 17.59.50.png

ソートすることができました。

Sort & Limit

もちろん、SortとLimitを組み合わせて使うこともできます。

{
  users(age_sort: DESC, limit: 2) {
    name
    age
  }
}
スクリーンショット 2019-04-11 18.00.34.png

まとめ

簡単な取得系処理を実装してみました。
実際にやってみると、すごく自由度が高いという感想と、処理を足していくうちにどんどん肥大化していくんじゃないか?などいろいろと思うことがありました。
その部分を解消できる方法も調べてみたいと思います。

次回もう少し難易度を上げた データ取得Lv2 に続きます!

17
12
0

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
17
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?