AWS Chaliceで爆速でREST APIを作ってみる



ChaliceはAWSサーバーレスアーキテクチャを使ったREST APIを簡単に開発できるPythonフレームワークです。
API以外にも単にAWSイベントをトリガにしたLambdaを作成することもできるそう。

というわけでサンプルがてらAPIを作ってみる。

インストール

>mkdir chalice
>cd chalice
>virtualenv venv
>venv\Scripts\activate
>pip3 install chalice
>chalice --version
chalice 1.21.4, python 3.8.6, windows 10

プロジェクトの作成、ローカル実行

>chalice new-project chalice_hello_world
>cd chalice_hello_world
>type app.py
from chalice import Chalice

app = Chalice(app_name='chalice_hello_world')


@app.route('/')
def index():
    return {'hello': 'world'}
~~~
>chalice local
Restarting local dev server.
Serving on https://127.0.0.1:8000
~~~
>curl https://127.0.0.1:8000
{"hello":"world"}

IAMユーザーの作成

ChaliceでデプロイするためのIAMユーザを作成します。
IAMポリシーには「AmazonAPIGatewayAdministrator」と「AWSLambdaFullAccess」とLambdaに与えるIAMロールが作れるように以下のインラインポリシーを付与します。
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "iam:Get*",
        "iam:List*",
        "iam:CreateRole",
        "iam:DeleteRole",
        "iam:PutRole*",
        "iam:DeleteRole*",
        "iam:PassRole"
      ],
      "Resource": "*"
    }
  ]
}
AWS CLIで作ったIAMのconfigureを登録します。
>aws configure --profile chalice
AWS Access Key ID [None]: *************
AWS Secret Access Key [None]: ******************************
Default region name [None]: ap-northeast-1
Default output format [None]: json

デプロイ

>cd chalice_hello_world
>chalice deploy --profile chalice
Creating deployment package.
Reusing existing deployment package.
Updating policy for IAM role: chalice_hello_world-dev
Creating lambda function: chalice_hello_world-dev
Creating Rest API
Resources deployed:
  - Lambda ARN: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXX:function:chalice_hello_world-dev
  - Rest API URL: https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/

>curl https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/
{"hello":"world"}
コマンド一発でデプロイが完了しました。
LambdaとAPI Gatewayが構成されています。

更新する場合は「app.py」等を編集して再度「chalise deploy」するだけ。
削除もコマンド一発。
>chalice delete --profile chalice
Deleting Rest API: XXXXXXXX
Deleting function: arn:aws:lambda:ap-northeast-1:XXXXXXXXXXX:function:chalice_hello_world-dev
Deleting IAM role: chalice_hello_world-dev

実践的なサンプル

from chalice import Chalice
import json
import logging
import numpy

logger = logging.getLogger()
logger.setLevel(logging.INFO)

app = Chalice(app_name='chalice_hello_world')

@app.route('/hello')
def index():
    return {'hello' : 'world'}

@app.route('/hello/{name}')
def index(name):
    return {'hello' : name}

@app.route('/hello',
           methods = ['POST'],
           content_types=['application/json'],
           cors=True)   # CORSを有効化
def post():
    request = app.current_request
    logger.info(json.dumps(request.json_body))
    return {
        'result': request.json_body['payload'],
    }

@app.route('/pi')
def index():
    return {'pi' : numpy.pi}
numpyは「requirements.txt」に書いて「pip3 install -r requirements.txt」でローカルはインストール。デプロイ時にはちゃんとインストールされてくれます。

デプロイ後の実行結果はこんな感じ、CloudWatch Logsにもちゃんと実行ログが流れます。
>curl https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/hello
{"hello":"world"}
>curl https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/hello/chalice
{"hello":"chalice"}
>curl -X POST -H "Content-Type: application/json" -d "{\"payload\":\"hello\"}" https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/hello
{"result":"hello"}
>curl https://XXXXXXXX.execute-api.ap-northeast-1.amazonaws.com/api/pi
{"pi":3.141592653589793}

個人的にSAMよりとっつきやすくていい感じです。
軽量なAPI作るならこれが一番楽そう。

そのほか使い方は公式のドキュメントやサンプルコードのリポジトリで。