Lazy Diary @ Hatena Blog

PowerShell / Java / miscellaneous things about software development, Tips & Gochas. CC BY-SA 4.0/Apache License 2.0

API GatewayからLambdaに渡される入力パラメタの形式

{
    "body-json": {},
    "params": {
        "path": {},
        "querystring": {
            "parameter1": "value1",
            "parameter2": "value2"
        },
        "header": {}
    },
    "stage-variables": {},
    "context": {
        "account-id": "999999999999",
        "api-id": "xxxxxxxxxx",
        "api-key": "xxx-xxx-api-key",
        "authorizer-principal-id": "",
        "caller": "XXXXXXXXXXXXXXXXXXXXX",
        "cognito-authentication-provider": "",
        "cognito-authentication-type": "",
        "cognito-identity-id": "",
        "cognito-identity-pool-id": "",
        "http-method": "GET",
        "stage": "xxx-xxx-stage",
        "source-ip": "xxx-xxx-source-ip",
        "user": "XXXXXXXXXXXXXXXXXXXXX",
        "user-agent": "aws-internal/3 aws-sdk-java/1.12.201 Linux/5.4.181-109.354.amzn2int.x86_64 OpenJDK_64-Bit_Server_VM/25.322-b06 java/1.8.0_322 vendor/Oracle_Corporation cfg/retry-mode/standard",
        "user-arn": "arn:aws:iam::999999999999:user/your-user-id",
        "request-id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
        "resource-id": "xxxxxx",
        "resource-path": "/path-to-resource"
    }
}
  • API GatewayでメソッドのオーソライザにLambda関数を指定した場合には、プロキシ統合の場合と同じ形式でLambda関数へパラメタが渡される。マッピングテンプレートは使用できない。

呼出元に返したいJSONの形式があらかじめ決められてるとか、JSONでなくてXMLでレスポンスを返したいとかの場合、けっきょくプロキシ統合は使えなくなる。なので、プロキシ統合の場合と同じパラメタの形式になるマッピングテンプレートがあればいいんだけど……

API Gatewayでオーソライザーの実行結果がGET/HEAD/OPTIONSで変わるように見える

背景

  • API Gatewayで同一リソースに対するGET/HEAD/OPTIONSを作成している。
  • どのメソッドにも同じオーソライザ(Lambda関数)を設定している。

事象

  • GETメソッドの[統合リクエスト]-[マッピングテンプレート]-[リクエスト本文のパススルー]を[リクエストの Content-Type ヘッダーに一致するテンプレートがない場合]に設定すると、GETリクエストではステータスコード200でレスポンスが返るが、HEADとOPTIONSリクエストでは403 Forbiddenが返る。403 Forbiddenのレスポンスボディは{"Message":"User is not authorized to access this resource"}

  • 一方、GETメソッドの[統合リクエスト]-[マッピングテンプレート]-[リクエスト本文のパススルー]を[テンプレートが定義されていない場合 (推奨)]に設定すると、GETリクエストではステータスコード403 Forbiddenでレスポンスが返る。403 Forbiddenのレスポンスボディは{"Message":"User is not authorized to access this resource"}。一方、HEADとOPTIONSリクエストでは200が返る。

原因

因果関係はよく分からなかったが、下記ヘルプに従いオーソライザで認可のキャッシュの[有効]のチェックを外すと、GET/HEAD/OPTIONSともオーソライザが成功した場合は200、失敗した場合は403 Forbiddenを返すようになった。 https://aws.amazon.com/jp/premiumsupport/knowledge-center/api-gateway-403-error-lambda-authorizer/#Resolve_.22not_authorized_to_access_this_resource.22_errors_from_the_Lambda_authorizer

Edgeのapplication modeの動作について

  • まず、Edgeのコマンドラインオプション一覧のようなページはmicrosoft.com内に見当たらなかった。ある程度まとまっているのは、kioskモードの説明*1と、プロキシの設定の説明*2くらい。
  • application mode自体はもともとChromiumにあった機能で、--appというオプションはここに記載がある。Chromiumコマンドラインオプション一覧は、オフィシャルサイト*3からリンクされている別サイト*4にある。
  • kioskモードでは常にウィンドウが全画面表示され、またCtrl+Wでウィンドウが閉じられない。application modeではウィンドウはウィンドウ表示になり、Ctrl+Wでウィンドウを閉じられる。
  • Microsoftのサイト内で、--appコマンドラインオプションについてある程度のオフィシャルさをもって提供されている情報は、Microsoft CommunityでのMS社員からのコメント*5くらい。
  • コマンドラインオプションを編集する方法でなく、Edgeの機能でapplication modeを起動するショートカットを作ることもできる。Edgeのメニューから[アプリ]-[このサイトをアプリとしてインストール]を実行し、[デスクトップ ショートカットを作成する]でショートカットを作成する。ただし、このショートカットは[このサイトをアプリとしてインストール]を実行したマシンでのみ有効で、他のマシンへコピーしてもapplication modeで起動するためのショートカットにはならない。
  • [このサイトをアプリとしてインストール]で作ったショートカットでは、msedge.exeでなくmsedge_proxy.exeを起動するようになっている。たとえばこんな感じで、--app-idはショートカット作成時に付与される一意なIDの模様。
"C:\Program Files (x86)\Microsoft\Edge\Application\msedge_proxy.exe"  --profile-directory=Default --app-id=embhbhbcpihgfgpjkmnapmogpkiamofo --app-url=https://www.google.co.jp/ --app-launch-source=4
  • このショートカットからEdgeを実行する場合、タスクマネージャで表示されるプロセスのコマンドラインmsedge.exeでもmsedge_proxy.exeでもなくpwahelper.exeになる。
"C:\Program Files (x86)\Microsoft\Edge\Application\pwahelper.exe" --app-id=embhbhbcpihgfgpjkmnapmogpkiamofo --ip-edge-aumid=Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!MSEDGE  --ip-override-url=https://www.google.co.jp/ --app-launch-source=4 --profile-directory="Default"

エンジニアのレゴブロックとドイッチュ限界のはざま

日本国内では情シの地位が低くてシステムをベンダに背負わせている企業が多いと聞く。そんな中でGoogle WorkspaceとMicrosoft Power Appsがスプレッドシートを取り込んだ。これまでマネージドサービスは「エンジニアのレゴブロック」*1だったが、これでブルックスの言うエンドユーザコンピューティング*2がマネージドサービス上で実現されることになったとすると……エンドユーザコンピューティングがローコード・ノーコードの文脈を伴うなら、どこかでドイッチュ限界にぶつかる。すると残るビジネスロジックは何か? 現状、FaaSは大規模なロジックの塊をデプロイすることを指向していないから、税の金額計算みたいな複雑なロジックを凝集したライブラリが、それをAPIとして提供するサーバのうえで残るか?

あるいは、大規模なシステムをエンドユーザコンピューティングで刷新しようとして、一部の機能をくくりだして実装するが、セカンドシステム症候群を回避できず、一部の機能だけでも刷新にたいへんな時間がかかり、くくりだされなかった部分が延々と生き延びる……というのがもう一つのシナリオか。

そういえば、エンドユーザコンピューティングにおけるセカンドシステム症候群……という話はあまり聞いたことがないな。自らのスキルや労力を自覚している状態では、機能を作ろうと思ったらそれだけ自分が大変だから、そもそもセカンドシステム症候群にかかりにくいとか、あるいはそもそも刷新がされなかったりするんだろうか?

エンドユーザコンピューティングによって作られたドキュメントのないアプリケーションは、その知識が個人に紐付くから、保守の引き継ぎが難しくなるはず(これは現状でも「秘伝のExcelシート」みたいな形で実在しているはず)。ロジックを書くのが特殊技能な間はここをリスクとしてとらえることができる。一方で、ロジックを書くのが特殊技能でなくなったら、システムの刷新は人の移動に伴って消滅するとともに、同様に発生もするはず(また必然的に犠牲的アーキテクチャの様相を取る)。アプリケーションが勝手に生えるなら経営者がそこを心配することもなくなるわけで、すると「保守」という概念が薄れていく?

*1:初出は次?: John Markoff, "Software Out There", The New York Times, https://www.nytimes.com/2006/04/05/technology/techspecial4/software-out-there.html, 2006/04/05.

*2:ブルックス「人月の神話 新装版」(ピアソン・エデュケーション,2002,p.185.

What curl can do and Invoke-WebRequest can't do

  • curl can show the raw request header and body with --trace option*1. There is no way to get the content of the request with Invoke-WebRequest.
  • curl can show the body of 5xx response. Invoke-WebRequest returns null when a server responds with status 4xx or 5xx, so you cannot view the body of the response.
  • curl shows the content of the 302 Found response when a server redirects the request. Invoke-WebRequest only shows the content of the 200 response in the same situation.