LoginSignup
10
5

More than 3 years have passed since last update.

Amplify API を Fetch や axios ぐらい簡単に使えるようにしたい

Last updated at Posted at 2020-12-11

前置き

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 を実務で使ってみたい方ぜひ!!

10
5
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
10
5