API Gateway + Lambda+Hasuraの構成をローカルで模倣してテストを行ったメモ

## 概要

AWSでPostgresを利用するには料金が高いので、Hasuraの無料枠を使ってRDSにデータを保存するアーキテクチャにしている。
今回、ローカルで単体テストを行うにあたり、下記の赤枠部分を作成した。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/adbb1de6-2f70-946a-3b25-272b9f304c5c.png)

dockerでDBやApolloサーバを動かし、`sam local start-api`でLambdaとAPIGatewayを動かした。

[この時点のソースコード](https://github.com/hibohiboo/RinneCircle/tree/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617)

## 環境
- Windows 10 Home

## 環境構築手順

### GraphQLサーバ(Hasuraモック)の作成

[Apollo ServerとPrismaではじめるGraphQL API開発入門](https://zenn.dev/eringiv3/books/a85174531fd56a/viewer/e25cc1) を参考に足回りを作成。

#### RDSの準備
dockerの公式コンテナを利用した。
[docker-compose.yml](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/docker/docker-compose.yml)

Apolloの入ったpackage.jsonを用意し、Docker上でセットアップ。
[container_build.sh](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/bin/container_build.sh)


#### RDSにテーブル作成
Prismaで定義し、マイグレーションを実施。
[schema.prisma](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/prisma/schema.prisma) , [migrate.sh](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/bin/migrate.sh)

### RDSにSeedデータ投入
Prismaで定義して実行。
[seed.ts](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/prisma/seed.ts) , [seed.sh](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/bin/seed.sh)

### Adminerで値が入ったことを確認。
接続情報は下記。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/903173b0-7828-d8b0-82d7-024eac27a55f.png)



### GraphQL定義
Hasuraからスキーマを取得。
[schema.graphql](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/GraphQL/schema.graphql)

### GraphQLサーバ（Apollo）作成
スキーマからTypescript用の型を作成。
[codegen.sh](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/bin/codegen.sh)

Prismaに型を認識させる。
```
npm run generate
```

GraphQLスキーマのQueryとMutationのリゾルバ関数を作成
[mutation/upsertScenario.ts](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/src/resolvers/mutation/upsertScenario.ts) , [query - getScenario.ts](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/src/resolvers/query/getScenario.ts) , [index.ts](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/src/resolvers/index.ts)

### 実行
[up.sh](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/localMock/bin/up.sh) で 実行。

アポロサーバによって、 http://127.0.0.1:4000/ GraphQLを試すことができる。
 Adminer によって、 http://127.0.0.1:8080 で DBを直接確認できる。 


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/8c526078-06c8-5ce3-5921-0700402668fb.png)

### APIGatewatyのローカル実行
[AWS CDKで作成したAPIGateway+Lambda(Node18)をローカルで動かしてみたメモ](https://qiita.com/hibohiboo/items/45a673ca70d42f3d1f4b)で動作させたものとほぼ同様。

dockerで起動しているローカルのGraphQLサーバと通信させるため、親のホストを利用する設定にしている。(`host.docker.internal` ... WindowのDocker for Desktop限定。Linuxは10.0.2.2と思われ）
`--env-vars `オプションで[環境変数上書き](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-cli-using-invoke.html)を起動時に実施。

[env.json](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/cdk/env.json) , [package.json](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/cdk/package.json)



```json
{
  "Parameters": {
    "GRAPHQL_ENDPOINT": "http://host.docker.internal:4000/",
    "GRAPHQL_SECRET": "Do not use in local environment."
  }
}
```

`npm run local-api`でAPIGateway起動。

http://127.0.0.1:3000 がドメインとなる。

## テスト実施
[StepCI](https://docs.stepci.com/)を利用。

[workflow.yml](https://github.com/hibohiboo/RinneCircle/blob/6f44e6be8b42fffa3f88bcb5c5641c9d89f9a617/packages/backend/workflow.yml)

成功。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99876/f4dc3180-3ea9-b5fb-83a6-458863e7d219.png)

**2023.06.13**

パラメータの先頭が数字だと、それ以降の文字列が送られないバグがあった。
7d8bb386-0f86-4dff-be34-86bb2f55b3662 → 7

[最新版のテンプレートエンジン](https://github.com/stepci/liquidless)では解決済なので、更新を行ったところ解決した。
```
pnpm add -D liquidless
```

[バグ報告](https://github.com/stepci/stepci/issues/134#issuecomment-1587768767)から[修正](https://github.com/stepci/liquidless/commit/94d42b2a5def72471426822f1fe1bb9d9a3bd02e)までのスピード感すごい。