サーバーレスな郵便番号検索APIを作成してみた

## 概要

AWSでサーバーレスな郵便番号検索をつくってみたの手順書です。
ファイルを置いて、プログラムを少し書くだけ簡単にできます。

## 必要なもの

AWSアカウント

## 利用するサービス

・　S３　：　郵便番号のCSVを格納

・　S３ Select　：　S3のデータをSQLライクに抽出する

・　Lambda　：　S3のCSVからレスポンスを返すメソッド

・　API GetWay　：　Lambdaの内容をAPI化する

### Step1:郵便局のCSVダウンロード

日本郵政のページから以下CSVをダウンロード。
文字コードがShiftJISなので、UTF8に変換しておく。

https://www.post.japanpost.jp/zipcode/download.html

またSQLをわかりやすくかけるように、以下のヘッダーを付与する。

```text
JISCode,OldPostCode,PostCode,PrefecturesNameKana,CityNameKana,TownNameKana,PrefecturesName,CityName,TownName,Note1,Note2,Note3,Note4,Note5,Note6
```

### Step２:S3にCSVデータをアップロード

バケットを作成の上、対象のCSVファイルをアップロード

![S3 Management Console 2019-12-30 20-53-20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/827e0db1-1081-ffd9-2c91-9b481e3d0234.png)

### Step3:S3 Selectを試してみる

S3 Selectタブ選択して、画面下の次へを押す。

![S3 Management Console 2019-12-30 18-38-30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/5320c162-b71c-8941-d428-5cb086d0016c.png)

SQLが入力できることを確認

![S3 Management Console 2019-12-30 18-39-05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/29109771-7cc6-ae86-0d99-de6ac204182a.png)

### Step４:Lambdaを作成

　・  言語はPython

　・  作成後、IMAロールにS3の読み取り権限を付与する

![S3Select - Lambda 2019-12-30 18-41-52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/9c3dc52c-e7a0-e161-4eae-ca10b8d2e1f2.png)

　・　対象のロールからS3ReadOnlyAccessを付与する

![IAM Management Console 2019-12-31 07-52-41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/43b7a7f2-5fad-d65f-1ab6-611cbfad27a9.png)


　・　ソースコードは以下にて作成

```python
import boto3
 
BUCKET_NAME = 'XXXXXX'
OBJECT_KEY = 'XXXXXX.CSV'
COMPRESSION_TYPE = 'NONE'

def lambda_handler(event, context):
    # APIのパラメーター
    postcode = event['postcode']
    # S3 Select
    query = 'select * from s3object s where PostCode =\'' + postcode + '\''
    s3 = boto3.client('s3')

    #S3.Client.select_object_contentの設定
    response = s3.select_object_content(
        Bucket=BUCKET_NAME,
        Key=OBJECT_KEY,
        ExpressionType='SQL',
        Expression=query,
        InputSerialization={
            'CSV': {
                'FileHeaderInfo': 'USE',
                'RecordDelimiter': '\n',
                'FieldDelimiter': ',',
            },
            'CompressionType': COMPRESSION_TYPE,
        },
        OutputSerialization={
            'JSON': {
                'RecordDelimiter': '\n'
            }
        }
    )
 
    # 結果を表示
    for payload in response['Payload']:
        if 'Records' in payload:
            records = payload['Records']['Payload']
            return records
```

### Step５:APIGetWayを作成

　・　RESTを選択、新しいAPIを選択、適当なAPI名を入力

![API Gateway 2019-12-30 18-59-49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/eda7aad9-2da9-13a6-09e1-d5fcb4230c2e.png)

　・　メソッドの作成、GETメソッドを選択、統合タイプをLambdaにして、Lambda関数名に上記でセットした名前にする

![API Gateway 2019-12-30 19-00-43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/36d02830-8064-80c5-c05f-f6d4f829064a.png)

　・　統合リクエストを選択

![API Gateway 2019-12-30 19-08-48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/41c2e6b4-8022-4c91-990f-4b46ea1bca90.png)

・　マッピングテンプレートにapplication/jsonと入力して、チェックをつけ、
　 テンプレートに設定するGETパラメータの値を入力

![API Gateway 2019-12-30 19-13-13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/a140da3f-49c8-6cbb-b21b-f09ba247ff55.png)

・　APIのデプロイを選択。

![API Gateway 2019-12-30 19-18-57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/e99a9dff-6a64-6622-a7bc-f46dccb6bfb8.png)

・　ステージ名をつけて、保存すれば・・・

![API Gateway 2019-12-30 19-19-23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/f4e9f232-844a-4746-c9ca-569c12471433.png)

### 完成！

完成したURLを叩くと、JSON形式で結果が返ってくる。
PostCodeがパラメーターになっている。

![あ.execute-api.ap-northeast-1.amaz.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/abd6a988-948e-09d0-b07f-9a28e871639d.png)

↓　レスポンス例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/230829/dd9bc817-b573-7d2c-c335-e85b9c35a9cc.png)

### 最後に

LamdbaでAPI作れて便利ですが、ただではないです。
Lamdbaは呼ばれるたびにお金がかかります。

あとパフォーマンスは要チェックです。