忘れた時に見るAWS Lambda用REST APIのキホン
はじめに
私はAWSでLambdaとAPI Gatewayを使ってAPIを構築することが多いのですが,Lmabdaからどのようにパラメータを取得するのか忘れてしまうことが多いので,APIの基礎と共にここにまとめておきます.
なんとなく,Web APIについて知っている前提での記述となります.
RESTful APIとは
RESTはREpresentational State Transfer (REST)の略で,現在のWeb APIの主流となっている設計思想である.RESTはよくアーキテクチャや設計思想であると強調される通り,標準化されているわけではなく,絶対に従う必要も無いし従わないと動かないということもない.
RESTは4つの原則から成る.
- アドレス可読性
- 提供されるリソースが一意のURLによって表現されること.
- 統一インターフェース
- リソースの操作(取得,作成,更新,削除)がHTTPメソッド(GET,POST,PUT,DELETE)を通して行われること.
- やりとりされるデータの形式はXMLまたはJSONで表される.
- ステートレス性
- リソースのやりとりが1回で完結すること.
- そもそもHTTPは基本的にステートレスである.
- 接続性
- 取得した情報に,別の情報へのリンクが含まれること.
- これにより,全てのリソースを把握する必要が無い.
この中で,REST APIの設計に大きく関わるのはアドレス可読性と統一インターフェースである.
一意で表されるリソースに対し,HTTPメソッドで操作をする,というのがREST APIのキホンである.
API設計の例を示す.
リソース | GET | POST | PUT | DELETE |
---|---|---|---|---|
user | 全ユーザー取得 | 新規ユーザー作成 | ユーザー情報一括更新 | ユーザー一括削除 |
user/1234 | ユーザー(id:1234)取得 | - | ユーザー(id:1234)情報更新 | ユーザー(id:1234)削除 |
このように,例えばuserというリソースに対してGETをすることで,全てのユーザー情報を取得出来る,というのがRESTの基本的な考え方である.
よって,例えば/get_user
のようなリソースは望ましくなく,URIは単にリソースのみを表す言葉にすべきである.
また,特定のユーザーを取得する場合もリクエストボディやクエリストリングでidを指定するのではなくuser/1234
のように一意のリソースとして扱うことが望ましい.
REST APIにおけるパラメータの渡し方
パラメータの種類
リソース(URI)+HTTPメソッドだけだと,必要な操作を実現出来ないことが多い.そこで,APIには主に3種類のパラメータの受け渡し方が用意されている.
- パスパラメータ(リクエストパラメータ)
パスパラメータは先程のuser/1234
の1234
の部分のように,特定のリソースに対してアクセスするために使うパラメータである.
以下のように表記・定義することで,{user_id}
部分に任意の値が入るこパスパラメータであることを表せる.
https://example.com/user/{user_id}
- クエリストリング(クエリパラメータ)
クエリストリングはパスパラメータのあとに記述し,変数名=値
の形式で表記する.
パスパラメータのあとに?を挟んで書き始め,複数付けたいときは&で結合する.
https://example.com/user?sort=asc&membership=paid
上記の例では,全てのユーザーを取得する際,sort=asc
で昇順に並び替え,membership=paid
で有料会員のみを取得するよう指示している.
- リクエストボディ
以下のように新規ユーザの登録をする際,登録するユーザの詳細な情報を添付したい場合がある.
POST https://example.com/user
そのような場合に使うのがリクエストボディで,主にjson形式で自由にパラメータを設定できる.
{
user_name: "john",
membership: "paid"
}
パラメータの渡し方
パラメータの渡し方はどれでも良いというわけではなく,メソッドに応じて最適な方法が存在する.
HTTPメソッド | クエリストリング | リクエストボディ | パス |
---|---|---|---|
GET | ◎ | ☓ | ○ |
PUT | ☓ | ◎ | ○ |
POST | ☓ | ◎ | ○ |
DELETE | ☓ | ☓ | ◎ |
- GETは取得するリソースをパスパラメータで識別し,取得の際に追加条件があればクエリストリングで指定する.
- PUT,POSTはパスパラメータで指定されたリソースに対し,リクエストボディの内容を作成/更新する.
- DELETEはパスパラメータで示されるリソースを削除する.
AWS Lambdaにおけるパラメータの参照
AWSではAPI GatewayとLambdaを組合わせてREST APIを作成することが多い.
参考:API Gateway から Lambda にパラメータを渡す
(ちょっと話が飛躍する気もするが,今回の本命はこの部分である.)
API GatewayからLambdaをプロキシ統合で接続し,Lambda側でパラメータを参照することを考える.このとき,各パラメータはLambda内から以下のように取得できる.(プログラムはPythonを想定する.)
lambdaでは全ての関数は以下のように定義される.
def handler_name(event, context):
各パラメータはevent
引数内に格納されている.
- パスパラメータ
以下のURIにアクセスする場合を考える.
https://xxx.execute-api.ap-northeast-1.amazonaws.com/dev/xxx/{foo}/{bar}
このとき,{foo}``{bar}
は以下のようにアクセスできる.
foo = event['pathParameters']['foo']
bar = event['pathParameters']['bar']
- クエリストリング
以下のURIにアクセスする場合を考える.
https://xxx.execute-api.ap-northeast-1.amazonaws.com/dev/xxx/{foo}/{bar}?hoge=hogege&fuga=fugaga
このとき,hoge``fuga
は以下のようにアクセスできる.
hoge = event['queryStringParameters']['hoge']
fuga = event['queryStringParameters']['fuga']
- リスエストボディ
以下のjsonで記述されたリクエストボディを含むリクエストを考える.
{
"aaa":"bbb"
}
このとき,aaa
は以下のようにアクセスできる.
import json
body = json.loads(event['body'])
aaa = body["aaa"]
print(aaa) #bbb
Discussion