1
/
5

森田ドラゴンのインターンシップ ~28日目~ SAM Swagger

こんにちは、高知からリモートインターンしている森田ドラゴンです。最近はCentOSをPCに入れて色々触りたいなと思ってます。Linuxを入れた暁には、マウスを破壊してコマンドラインしか使えない体にしようと思ってます(箸の持ち方を矯正される子供みたいで面白いですね)。

前回、Pythonのテストコードが書き終わったので、残っているタスクは以下になります。

・SwaggerなしでSAMの作成
・SwaggerをimportしてSAMを作成
・アップロードしてjs, awsリソースのテスト

Swaggerは、APIの構造を効率的に定義できるドキュメントだと勘違いしていましたが、本当の使い方はCloudFormationのように、YAMLで設計図を書くことにあるみたいです。

SwaggerなしでSAMの作成

SAMの作成といっても、ほとんど触ることはありません。AWS::Serverlss::Functionを設定してあげればそれで終了です。

ApiFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      Role: !GetAtt OtenkiIamRole.Arn
      CodeUri: weather_api/
      Handler: app.lambda_handler
      Runtime: python3.7
      Events:
        HelloWorld:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /
            Method: post

AWS::Serverlss::FunctionはLambdaを設定するためのものですが、API GWも作ってくれます。「ではAPI GWは作らなくていいのか?」という疑問が湧きましたが、正解は公式ドキュメントに書いてありました。

https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/serverless-sam-template.html

we recommend that you create APIs by specifying this resource type as an event source of your AWS::Serverless::Function resource.

このAPI GWのリソースはServerlss::Functionのイベントソースとして返してあげたほうがいいですよ〜

久しぶりにバッチりと、しかも公式で答えが見つかったのでスッキリしました。

curlが通らない

SAMの雛形はできたので、さっそくローカルリソースを curlで叩いてテストしました。

curl http://127.0.0.1:3000/ -d \"{\id\:\"4000040\", \"date\": \"0\"}\" -H "Content-Type:application/jsonただ、

すると、そんなデータはないぞとエラーが発生しました。evenをprintして確認して見ましたが、データは遅れているみたいです。自分の知らないPythonの仕様か、API GWからLambdaに送られる際に特殊なルールがあるのか、色々考えましたが、結局コマンドをミスしていただけでした。

curl http://127.0.0.1:3000/ -d "{\"id\":\"400040\", \"date\": 0}" -H "Content-Type:application/json" 

-dオプションのあとを見てください。 -d オプションの後に、postしたいデータを送るのですが、データは" ダブルクォーテーションでくくる必要があります。 最初に打ったコマンドでは、タブルクォーテーションをエスケープしてしまっていたので、データを受け付けてもらえませんでした。

ちなみにシングルクォーテーションで、内部のjsonを定義するとエラーが起きます。Python的にはシングルクォーテーションとダブルクォーテーションを区別しませんが、API GWからのeventのjsonがシングルクォーテーションで定義されているため、データの区切りがおかしくなりエラーが起きます。

SwaggerをSAMにimport

SwaggerをSAMにimportしてあげるには、API GWに以下の記述を追加します

DefinitionBody:
  'Fn::Transform':
    Name: 'AWS::Include'
      Parameters:
        Location: ~swaggerが置いてある場所のurl~

そしてSwaggerの方には、以下を追加します。

x-amazon-apigateway-integration:
  httpMethod: post
  type: aws_proxy
  uri:
    Fn::Sub: arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${ApiFunction.Arn}/invocations

x-amazon-apigateway-integrationはドキュメントにあるように、OpenAPI Operation オブジェクトの拡張プロパティだそうです。SwaggerでFn::Subが使えたりと、色々よしなにやってくれるみたいですが、動作を完全に理解していないので、また調べ直して見たいと思います。

Invalid permissions on Lambda function

SAMがデプロイできたので、テストしてみると上のエラーが。Permissionエラーなので、「IAMロールを調整すればいいだろう」と思っていましたが、何故かRoleが付与されません。

AWSコンソールから付与しても、反映された様子がない。ドキュメントの通りにコマンドを打っても、同じ結果だったので、SAMの記述をもう少し調べてみようと思います。

感想

SAMとSwaggerを連携させる部分で、どこでエラーが発生しているのか特定するのが大変でした。単純に文法をミスしている可能性もあるので、その場合はエラー文の指示通りに記述したり、検索をかけても解決しない場合が多いです。

SAMのあたりはもう少しサンプルを作って見たいです。

株式会社サーバーワークスでは一緒に働く仲間を募集しています
同じタグの記事
今週のランキング
株式会社サーバーワークスからお誘い
この話題に共感したら、メンバーと話してみませんか?