ブラウザからLambda Functionを呼び出して何かさせたい
ブラウザからLambda Functionを呼び出して何かさせたい:
ブラウザからJSを使ってAPI Gateway経由させてリクエストを処理させる方法に関しては記事を見つけたんですが
そんなめんどくさいことをしたくない()という超ものぐさ思考
やってみて思ったのは、Lambdaを起動して何かをさせるだけならURL一発で動くものが作れるという、いい時代になったなあ、っていう小学生並みの感想が浮かぶやつだった(何)
あとはまあ、IoT Buttonとかあの辺と同じぐらいの気軽さを、ブラウザからアクセスするやり方でやってみたかったんですよ。
セキュリティとか知らんがな状態なので、URL非公開にするとか、自衛は必要かと思う。
まあ個人でやるとかそのレベルを想定していて、実際にできちゃったから記事にしてみた次第です。
そもそも重要な場面ではちゃんとセキュリティとか考慮してね!
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-on-demand-https-example-configure-event-source_1.html
これに従って作っていくと、LambdaとAPI Gatewayがセットで作れるので、あとはブラウザからURL叩いた時にリクエストを受理できるように調整すると、いい具合にできる。
筆者はPythonを使っているので、Pythonのブループリントを利用したけど、内容としては検索で引っかかるどのブループリントを使っても同じ内容っぽい。
とはいうものの、これだけだと役に立たなさすぎる記事が出来上がるので、つまづきポイントを解説しようと思う
API Gatewayに対して、GETリクエストを送信した場合、Lambdaの起動時に以下のようなデータが、eventに入った状態で起動します
paramXXがGETリクエストに含まれるクエリになります。
なので、Lambda関数のハンドラは lambda_function.lambda_handler として
のような感じにしてやると、パラメータがそのまま取得できます。便利。
当然なんですけど、Lambda関数で return True とかやってもAPI Gatewayは認識してくれないので、ブラウザ側にはステータスコード400が返ったりするわけです
API Gatewayに返すレスポンスとしては
まあ見てわかると思うんですけど、Lambdaの実行結果をbodyに入れて、成功か失敗かは、StatusCode200か400か、みたいなごく必要最低限の実装でよい場合は、
みたいな感じでやればよいと。雑だけどこれで動く。
(正直ガバガバすぎて怒られそうだけど)できます
API Gatewayのページに飛ぶと、Lambdaのブループリントで作ったAPIが既に表示されていると思います。
このAPIのページに入って、メソッドの実行についてANYになっている部分に移動します。
クライアント→メソッドリクエスト→統合リクエスト→Lambda関数
クライアント←メソッドレスポンス←統合レスポンス←Lambda関数
と表示される画面。
メソッドリクエストの設定をします。
URLクエリ文字列パラメータの設定で、
クエリ文字列の追加から、GETリクエストに含まれるクエリの設定をします。
必須のチェックを入れると、上記のリクエストの検証を有効にしていると、必須チェックを実施してくれます。
これで、(セキュリティ的には問題ありだが)ブラウザからURLに対してリクエストして、受理されるようになりました。
筆者はLambda関数の内部で、正当なリクエストかどうかのチェックを設けました
(そのぐらいならすぐできるわ、って思って…超雑なだけなんだけどさ)
各APIのページの アクション→APIのデプロイ でデプロイ先のステージを指定してデプロイすればOK
左ペインにあるステージ → デプロイ先のステージを選択すると、URLが表示されているので、このURLに対して、
https://~~~~/ステージ/リソースのところに表示されているAPIの階層
でアクセスできるようになります。
AWS EC2の起動ボタン
サーバに上げて動かすほどじゃないけどこの機能がほしい、みたいな場面だったのでAPI Gateway → Lambda は最適じゃねえかな!って思った。
起動ボタンのHTML自体はローカルにおいておくという方法が使えるし。
ブラウザからJSを使ってAPI Gateway経由させてリクエストを処理させる方法に関しては記事を見つけたんですが
そんなめんどくさいことをしたくない()という超ものぐさ思考
やってみて思ったのは、Lambdaを起動して何かをさせるだけならURL一発で動くものが作れるという、いい時代になったなあ、っていう小学生並みの感想が浮かぶやつだった(何)
あとはまあ、IoT Buttonとかあの辺と同じぐらいの気軽さを、ブラウザからアクセスするやり方でやってみたかったんですよ。
注意
セキュリティとか知らんがな状態なので、URL非公開にするとか、自衛は必要かと思う。まあ個人でやるとかそのレベルを想定していて、実際にできちゃったから記事にしてみた次第です。
そもそも重要な場面ではちゃんとセキュリティとか考慮してね!
何ができたの
- URLのみでAPI Gatewayへリクエストを送信(してちゃんと受理される)できた
- GETリクエストを投げると、Lambdaの実行結果が返ってくるようにできた
- GETリクエストにパラメータを持たせて、その内容をLambdaに渡して処理ができた
どうやったの
https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/with-on-demand-https-example-configure-event-source_1.htmlこれに従って作っていくと、LambdaとAPI Gatewayがセットで作れるので、あとはブラウザからURL叩いた時にリクエストを受理できるように調整すると、いい具合にできる。
筆者はPythonを使っているので、Pythonのブループリントを利用したけど、内容としては検索で引っかかるどのブループリントを使っても同じ内容っぽい。
とはいうものの、これだけだと役に立たなさすぎる記事が出来上がるので、つまづきポイントを解説しようと思う
Lambdaにどのようにリクエストが渡るのか
API Gatewayに対して、GETリクエストを送信した場合、Lambdaの起動時に以下のようなデータが、eventに入った状態で起動しますevent
{ …略 "queryStringParameters": { "param1": "hogerahogera", "param2": "asdftyuio" } …略 }
なので、Lambda関数のハンドラは lambda_function.lambda_handler として
lambda_function.py
def lambda_handler(event, context): payload = event["queryStringParameters"] param1 = payload["param1"] param2 = payload["param2"]
API Gateway側で処理されるレスポンスの形式を作る
当然なんですけど、Lambda関数で return True とかやってもAPI Gatewayは認識してくれないので、ブラウザ側にはステータスコード400が返ったりするわけですAPI Gatewayに返すレスポンスとしては
- statusCode
- body
- headers
まあ見てわかると思うんですけど、Lambdaの実行結果をbodyに入れて、成功か失敗かは、StatusCode200か400か、みたいなごく必要最低限の実装でよい場合は、
lambda_function.py
def create_response(err,result): if err: status = "400" else: status = "200" return { 'statusCode': status, 'body': result, 'headers': { 'Content-Type': 'application/json', }, }
URL直でAPI Gatewayに処理を受理させる方法
(正直ガバガバすぎて怒られそうだけど)できますAPI Gatewayのページに飛ぶと、Lambdaのブループリントで作ったAPIが既に表示されていると思います。
このAPIのページに入って、メソッドの実行についてANYになっている部分に移動します。
クライアント→メソッドリクエスト→統合リクエスト→Lambda関数
クライアント←メソッドレスポンス←統合レスポンス←Lambda関数
と表示される画面。
メソッドリクエストの設定をします。
- 認証:なし
- リクエストの検証:必要に応じて設定する
- APIキーの必要性:False
URLクエリ文字列パラメータの設定で、
クエリ文字列の追加から、GETリクエストに含まれるクエリの設定をします。
必須のチェックを入れると、上記のリクエストの検証を有効にしていると、必須チェックを実施してくれます。
これで、(セキュリティ的には問題ありだが)ブラウザからURLに対してリクエストして、受理されるようになりました。
それにしてもセキュリティがガバガバすぎるのでは?
筆者はLambda関数の内部で、正当なリクエストかどうかのチェックを設けました(そのぐらいならすぐできるわ、って思って…超雑なだけなんだけどさ)
APIのデプロイ
各APIのページの アクション→APIのデプロイ でデプロイ先のステージを指定してデプロイすればOK左ペインにあるステージ → デプロイ先のステージを選択すると、URLが表示されているので、このURLに対して、
https://~~~~/ステージ/リソースのところに表示されているAPIの階層
でアクセスできるようになります。
筆者が作ったもの
AWS EC2の起動ボタンサーバに上げて動かすほどじゃないけどこの機能がほしい、みたいな場面だったのでAPI Gateway → Lambda は最適じゃねえかな!って思った。
起動ボタンのHTML自体はローカルにおいておくという方法が使えるし。
コメント
コメントを投稿