AWS
S3
CloudFront
lambda
APIGateway

AWS lambda + API Gateway で郵便番号検索APIを作った

More than 1 year has passed since last update.


はじめに

勉強目的で、AWS lambdaを使って郵便番号検索APIを作ってみました。


概要

任意の郵便番号をURLに含めてアクセスすると、該当する住所の情報が取得できるようにします。


構成図

ざっくりとした全体の構成は下図のとおりです。

jp-zip-api.png


lambdaの作成

Edit code inlineを選択し、テキストエリアにコードを貼り付けます。

from __future__ import print_function

import json
import os
import boto3
from botocore.exceptions import ClientError

print('Loading function')

def respond(content=None, status_code=200):
return {
'statusCode': status_code,
'body': content,
'headers': {
'Content-Type': 'application/json',
},
}

def lambda_handler(event, context):

zip_code = event['zip_code']
kana_type = event['kana_type']
version = event['version']
key = os.path.join(kana_type, version, zip_code[0:3] + '.json')

try:
s3 = boto3.client('s3')
response = s3.get_object(Bucket='jp-zip', Key=key)
json_data = json.load(response['Body'])
if zip_code in json_data:
return respond({'address': json_data[zip_code]})
except ClientError:
return respond('Zip code (' + zip_code + ') is invalid.', 404)

return respond('Address is not found by zip code (' + zip_code + ').', 404)

関数内でやっていることは下記のとおりです。


  • event変数から、必要なパラメータを取り出す

  • S3のjp-zipバケットに郵便番号先頭3桁ごとにjsonファイルが格納されているので、取得する


    • jsonファイルをどう作成したのかは、別の機会に投稿することにします



  • 取得した内容をjsonとして読み込む

  • jsonデータの中から目的の郵便番号が存在するかチェックし、存在すれば内容を返す


設定

いくつかポイントを列挙します。


  • Handler


    • {ファイル名}.{関数名}を入力します


    • Edit code inlineの場合は、ファイル名は特にチェックしていない気がします



  • Existing Role


    • lambda関数内でAWSのサービス(例: S3)を利用する場合は、アクセス権限が必要になるので、IAMで適切に設定します



Lambda_config.png


トリガーの設定

API Gatewayをトリガーに設定します。

Lambda_triggers.png


lambdaのテスト

ActionsのプルダウンメニューからConfigure test eventを選択し、必要なパラメーターをjson形式で設定し、Save and testボタンをクリックします。

Lambda_test_parameters.png

テストに成功すると、下記のようにログが出力されます。

Lambda_test_result.png


参考URL


APIの作成

郵便番号をパラメータとして、住所を検索するAPIを作成します。


リソースの作成

API Gatewayにて、/jp-zip/{zip_code}というリソースを作成し、{zip_code}に任意の郵便番号を指定するようにします。

パラメータは中括弧({})で囲うようにします。


メソッドの作成

/jp-zip/{zip_code}にGETメソッドを作成します。

API_Gateway.png


本文マッピングテンプレート

統合リクエストのリンクから、本文マッピングテンプレートの設定をします。

メソッドリクエストパラメータをlambda関数に引き渡します。

API_Gateway_lambda.png


  • $input.params(x)


    • パラメータ名文字列 x が指定された場合に、パス、クエリ文字列、またはヘッダー値から(この順番で)メソッドリクエストパラメータの値を返します。




ステージの作成

ステージを作成し、必要なパラメータをステージ変数に追加します。

郵便番号データの読み仮名の種別と更新年月日をステージ変数にセットしました。


API Gatewayのテスト

パス、ステージ変数にテストしたい内容を入力し、テストすると、レスポンスが出力されます。

API_Gateway_test_result.png


参考URL


おわりに

サーバーを常設することなく、データベースも使わずに実装できたので、非常に安価に運用できる気がしてます。

様子をみてAPI公開するかもしれません。

Google Map APIも制限がキツくなったみたいですし。

Google Maps Geocoding API Usage Limits  |  Google Maps Geocoding API

それでは、また。