Aurora Serverless Data API のローカル開発環境を構築する方法

## はじめに
[DynamoDB は公式に Docker イメージとしてローカル開発環境が提供されている](https://hub.docker.com/r/amazon/dynamodb-local/)のに対し、Aurora Serverless の Data API はローカル開発環境が提供されていません（2020年4月18日現在）。

調査したところ非公式ですが、 Data API のローカル開発環境が GitHub （下記リンク）で公開されていたため、その内容を紹介させていただきます。

[![koxudaxi/local-data-api - GitHub](https://gh-card.dev/repos/koxudaxi/local-data-api.svg?fullname=)](https://github.com/koxudaxi/local-data-api)

## AWS Aurora Serverless の Data API とは？

[AWS公式ドキュメント](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/data-api.html)をご参考願います。


## ローカル Data API の仕組み
ローカル Data API は、以下のコンポーネントで実現されています。

- データベース（MySQL または PostgreSQL）の Docker コンテナ

- データベース向けプロキシサーバの Docker コンテナ

プロキシサーバが API となり、Aurora Serverless の Data API と同じフォーマットのレスポンスを返してくれます。

## ローカル Data API の使い方

データベースの種類ごとに Compose ファイルが提供されているため、Docker Compose を使った手順を紹介します。

### 1. ローカル Data API 用コンテナを起動する
リンク先の Compose ファイル（[MySQL 5.6](https://github.com/koxudaxi/local-data-api/blob/master/docker-compose-mysql.yml) または [PostgreSQL 10.7](https://github.com/koxudaxi/local-data-api/blob/master/docker-compose-postgres.yml)）をダウンロードして、同ディレクトリで docker-compose コマンドを実行します。

```bash:
$ docker-compose up -d

$ docker-compose ps
             Name                           Command              State           Ports         
-----------------------------------------------------------------------------------------------
test_db_1               docker-entrypoint.sh postgres   Up      0.0.0.0:5432->5432/tcp
test_local-data-api_1   /start.sh                       Up      0.0.0.0:8080->80/tcp                                        
```
データベースコンテナが PostgreSQL の場合5432ポート、MySQL の場合3306ポートで公開されます。Data API は8080ポートで公開されます。[^1]
[^1]: ローカル Data API に対して、**ローカル Lambda 等の他コンテナからアクセスする場合は、コンテナをローカル Data API と同じ Docker ネットワークで実行する必要があります**。また、**他コンテナからアクセスする際のURLは「 http://local-data-api:80 」となります**。

### 2. AWS CLI からローカル Data API へ SQL を発行する

**エンドポイントURLとして「 http://127.0.0.1:8080 」を指定して**、AWS CLI でバージョンを確認する SQL を発行します。
このケースでは「--database」オプションはなくてもよいです。特定のデータベースに対して操作をする場合にご利用ください。

```bash
aws --endpoint-url http://127.0.0.1:8080 rds-data execute-statement --resource-arn "arn:aws:rds:us-east-1:123456789012:cluster:dummy" --sql "select version()"  --secret-arn "arn:aws:secretsmanager:us-east-1:123456789012:secret:dummy" --database test
{
    "numberOfRecordsUpdated": 0,
    "records": [
        [
            {
                "stringValue": "PostgreSQL 10.7 on x86_64-pc-linux-musl, compiled by gcc (Alpine 8.3.0) 8.3.0, 64-bit"
            }
        ]
    ]
}
```


### 3. AWS SDK for Python (Boto3)  からローカル Data API へ SQL を発行する


**エンドポイントURLとして「 http://127.0.0.1:8080 」を指定して**、AWS SDK for Python (Boto3)  でバージョンを確認する SQL を発行します。
このケースでは「database」引数はなくてもよいです。特定のデータベースに対して操作をする場合にご利用ください。

```bash
$ ipython

In [1]: import boto3; client = boto3.client('rds-data', endpoint_url='http://127.0.0.1:8080') 

In [2]: client.execute_statement(resourceArn='arn:aws:rds:us-east-1:123456789012:cluster:dummy', secretArn='arn:aws:secretsmanager:us-east-1:123456789012:secret:dummy', sql='select version()', database='test')

Out[2]: 
{'ResponseMetadata': {'HTTPStatusCode': 200,
  'HTTPHeaders': {'date': 'Sat, 18 Apr 2020 13:51:27 GMT',
   'server': 'uvicorn',
   'content-length': '146',
   'content-type': 'application/json'},
  'RetryAttempts': 0},
 'numberOfRecordsUpdated': 0,
 'records': [[{'stringValue': 'PostgreSQL 10.7 on x86_64-pc-linux-musl, compiled by gcc (Alpine 8.3.0) 8.3.0, 64-bit'}]]}
```

### さいごに
サーバレスアーキテクチャによる開発をする際、せっかく SAM で API Gateway + Lambda をローカル環境でテストできるのに Data API だけクラウド環境というのはナンセンスだと思っていました。なので、この試みを知った時感動しました。（~~海外~~国内の有志に本当に感謝です）

Data API は、特定のユースケースにおいては魅力的なサービスですが、昨年（2019年）に東京リージョンでリリースされたばかりであるため、日本語の情報が少ない状況です。~~海外~~国内有志の試みを紹介しているだけですが、この記事が誰かのお役に立てましたら幸いです。
最後までお読みいただきまして、ありがとうございました！