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

## 前置き

2020年春ぐらいから Amplify を使い始めていくつか案件をこなしてきました。
少人数開発でかなりの生産を発揮するプラットフォームだと思います。

ただAmplify API(GraphQL)を使っていく上で課題となったのが、
案件メンバーを増やしずらいという点です。

チーム開発をどうしたら快適になるかという点を考えています。


## Amplify API(GraphQL)　

Amplify はGraphQL クライアントを自動生成してくれます。便利です。

ただimport が面倒だったり長いです。


```ts
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

```ts
import { * as apiUtil} from "src/apiUtil";

await api.createQuery("read", {
   userID: currentUser.id,
   reportID: r.id,
});
```

#### get

```ts
import { * as apiUtil} from "src/apiUtil";
const user = await apiUtil.getQuery("user", onUpdateUser.id);
```

#### delete

```ts
import { * as apiUtil} from "src/apiUtil";

 await apiUtil.deleteQueries("like", { id: like.id });
```


ほとんどのコードはいつも同パターンで、モデル名さえあれば生成できました。

axios ぐらいの感覚で使えるようになったので、
これならワンチャン Amplify 未経験者でも読み書きできるのではないか（？！）と
期待しています。


## 生成されたコードをさらにまとめる意味はあるのか？
好みもあるとは思いますが、チーム開発においてはメリットがあると思います。

- Amplify GraphQL に明るくない人でも、axiosぐらいの感覚で呼び出せるようになる。（メンバーが増やしやすくなる！！
- 多くのモデルにアクセスしたい時にコードが読みやすくなる。
- 共通処理が入れれるようになる。エラー表示など。


## 中はどんな処理にしたの？

query をまとめて変数に展開して、引数かで取得するようにしていました。
list の時は、複数軽になるのが面倒かな？と思ったのですが、単純に最後をsをつけているだけの
ルールだったので助かりました。

study ⇨  studies みたいな処理がなくてよかった・・


```ts
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 するパターンですが、
それもすっきりするようにしてみました。

```ts
      const parmas = formActivities.map((activity: any, index: number) => {
        return {
          id: activity.id,
          userID: currentUser.id,
        };
      });

      await createQueries("Activity", parmas);
````

### 実装したコード

```ts
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 してます。


## 作成した共通関数

https://github.com/coa00/amplifetch/blob/master/index.ts

ライブラリ化したいのですが時間がなくてできないです

# チームメンバーを募集しています！

私は、今、O: という会社で Amplify と ReactNative, React Native Web で
sass を作っています。

現在メンバーを募集しています。
Amplify に興味があってやってみたい方、お気軽に応募ください！
業務経験なし、副業、リモート OKです。
Amplify を実務で使ってみたい方ぜひ！！

https://www.wantedly.com/projects/542233f