前置き
2020年春ぐらいから Amplify を使い始めていくつか案件をこなしてきました。
少人数開発でかなりの生産を発揮するプラットフォームだと思います。
ただAmplify API(GraphQL)を使っていく上で課題となったのが、
案件メンバーを増やしずらいという点です。
チーム開発をどうしたら快適になるかという点を考えています。
Amplify API(GraphQL)
Amplify はGraphQL クライアントを自動生成してくれます。便利です。
ただimport が面倒だったり長いです。
import { API, graphqlOperation } from "aws-amplify";
import {
  listCategorys,
} from "graphql/queries";
    async function fetchCategories() {
      const res = await API.graphql(
        // @ts-ignore
        graphqlOperation(listCategorys, {})
      );
      _setCategories(res.data.listCategorys.items);
    }
レスポンスがこれまでのapi開発に慣れている人にとっては、
少し特殊だったりします。
共通処理は全てライブラリの中に入れてみる
生成されたコードを使って呼び出す場合
- import 文はだいたい同じ
- API.graphql ~ res.data 以降の記述は同じパターンで
といったコードたくさん書くことになります。
まとめれそうなのでまとめてみました。
list
import { * as apiUtil} from "src/apiUtil";
const categories = await apiUtil.listQuery("Category", {});
mutations
import { * as apiUtil} from "src/apiUtil";
await api.createQuery("read", {
   userID: currentUser.id,
   reportID: r.id,
});
get
import { * as apiUtil} from "src/apiUtil";
const user = await apiUtil.getQuery("user", onUpdateUser.id);
delete
import { * as apiUtil} from "src/apiUtil";
 await apiUtil.deleteQueries("like", { id: like.id });
ほとんどのコードはいつも同パターンで、モデル名さえあれば生成できました。
axios ぐらいの感覚で使えるようになったので、
これならワンチャン Amplify 未経験者でも読み書きできるのではないか(?!)と
期待しています。
生成されたコードをさらにまとめる意味はあるのか?
好みもあるとは思いますが、チーム開発においてはメリットがあると思います。
- Amplify GraphQL に明るくない人でも、axiosぐらいの感覚で呼び出せるようになる。(メンバーが増やしやすくなる!!
- 多くのモデルにアクセスしたい時にコードが読みやすくなる。
- 共通処理が入れれるようになる。エラー表示など。
中はどんな処理にしたの?
query をまとめて変数に展開して、引数かで取得するようにしていました。
list の時は、複数軽になるのが面倒かな?と思ったのですが、単純に最後をsをつけているだけの
ルールだったので助かりました。
study ⇨ studies みたいな処理がなくてよかった・・
export async function getQuery(target: string, id: string) {
  let res;
  const queryName = `get${pascalCase(target)}`;
  try {
    //@ts-ignore
    res = await API.graphql(graphqlOperation(queries[queryName], { id }));
    //@ts-ignore
    const data = res.data[queryName];
    // console.log(`getQuery ${target} ${id}`, data);
    return data;
  } catch (error) {
    store.dispatch(app.actions.setError("通信エラーが発生しました"));
    console.error(error);
    return null;
  }
}
Type も Targe から動的に取得できたらと思ったんですが、
いい方法が思いつかなかったです。(こうしたらいいよって思った方ぜひコメントください)
おまけ)配列の create
一番面倒だったのは配列でCreate するパターンですが、
それもすっきりするようにしてみました。
      const parmas = formActivities.map((activity: any, index: number) => {
        return {
          id: activity.id,
          userID: currentUser.id,
        };
      });
      await createQueries("Activity", parmas);
実装したコード
export async function createQueries(
  target: string,
  variables: any[],
  noGroup?: boolean
) {
  const tasks = [] as any[];
  variables.forEach(async (variable) => {
    const queryName = getQueryName(target, variable);
    const input = await getInput(variable, noGroup);
    console.log(target, queryName, input);
    const task = API.graphql(
      //@ts-ignore
      graphqlOperation(mutations[queryName], {
        input,
      })
    );
    tasks.push(task);
  });
  let resAll;
  try {
    resAll = await Promise.all(tasks);
    console.log("result:", resAll);
  } catch (error) {
    store.dispatch(app.actions.setError("通信エラーが発生しました"));
    console.error(target, error);
  }
  return resAll;
}
中で、Promise.all してます。
作成した共通関数
ライブラリ化したいのですが時間がなくてできないです
チームメンバーを募集しています!
私は、今、O: という会社で Amplify と ReactNative, React Native Web で
sass を作っています。
現在メンバーを募集しています。
Amplify に興味があってやってみたい方、お気軽に応募ください!
業務経験なし、副業、リモート OKです。
Amplify を実務で使ってみたい方ぜひ!!
