あらすじ
1.Apollo+Expressで始めるGraphQL超入門 ~ GraphQLをざっくり理解する
はじめに
前回の続きをやっていきます。
そのため使用するソースや環境構築は あらすじ を参照してくだい。
今回はデータの取得について色々書いていこうと思います。
※ 筆者はまだまだ初心者です。間違った解釈や実装などがあればご指摘お願いします。
Select
GraphQLは、必要なときに必要なものを取得することできます。
いらないデータは指定しなければ取得されません。
type User {
id: Int
name: String
age: Int
created_date: String
}
User
に対して id
と name
があればOKであればクエリにそう書きましょう。
{
users {
id
name
}
}
SQLのSELECTみたいな感じですね。
Limit
実装
const typeDefs = gql`
type User {
id: Int
name: String
age: Int
created_date: String
}
type Query {
- users: [User]
+ users(limit: Int): [User]
}
`;
typeDefs
の Query
の users
に対して引数を設定します。
limit
は数字がくるように設定しました。
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
+ }
}
};
resolvers
の Query
に引数が渡るように設定しました。
args
に引数が代入されます。
あとは、渡された limit
の数字に沿って処理を行うだけです。
※ コードの書き足しを行ったらnodeタスクを再起動してください
実行
{
users(limit: 3) {
id
name
}
}
Limit Done!
Sort
Users
を年齢でソートかけてみましょう。
年齢の降順、昇順が行えるように設定します。
実装
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
が指定される想定です。
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
}
}
ソートすることができました。
Sort & Limit
もちろん、SortとLimitを組み合わせて使うこともできます。
{
users(age_sort: DESC, limit: 2) {
name
age
}
}
まとめ
簡単な取得系処理を実装してみました。
実際にやってみると、すごく自由度が高いという感想と、処理を足していくうちにどんどん肥大化していくんじゃないか?などいろいろと思うことがありました。
その部分を解消できる方法も調べてみたいと思います。
次回もう少し難易度を上げた データ取得Lv2 に続きます!