こんにちは。高知からインターンしている森田ドラゴンです。Youtuberではありません。実は月曜日もインターンさせていただいていて、お天気apiを完成させてやろうと意気込んでいたんですが、SAMのデプロイで詰まってしまいました・・・。
無理せず、もっと早く質問するべきでした。うーん、構成的にはそこまで難しいことをやっていないので、記述ミスがあるはずだと思い、sampleと見比べていたり、エラーをそのまま調べたりしていたんですが、うまく解決できませんでした。反省します。
SAMとSwagger
前回までにSAMのテンプレートと、Swaggerのテンプレートはできあがっていました。ただ、お天気APIの仕様改変に伴い、2つのyamlも変更する必要がありました。yamlの変更点と追加点は
・post から get にリクエストを変更
・CORSを許可する
2つの作業を切り分けて行えば、エラーを切り分ける作業に時間を取られることもなかったなと思います。この2つと、自分がよくわかっていなかった、SwaggerとSAM templateのつながりを実験しながら進めた結果、エラーにはまったんじゃないのかなと思います。
ちなみにAPI GWに CORSを許可するにはSAMのテンプレートとLambdaのreturnを編集してあげるだけです。
Globals:
Api:
# corsの設定はglobalじゃないとダメっぽい
Cors:
AllowMethods: "'OPTIONS,GET'"
AllowHeaders: "'Content-Type'"
AllowOrigin: "*" #この部分にローカルホストや、ウェブサイトのurlを代入する
テンプレートはGlobals でApiのCORSを設定して上げます。Globalsじゃないとダメみたいです。
"headers": {
"Access-Control-Allow-Headers": "Content-Type",
"Access-Control-Allow-Methods": "GET,OPTIONS",
"Access-Control-Allow-Origin": "*"
},
"body" : json.dumps(body, ensure_ascii
Lambdaでも同じようにヘッダーに設定してあげれば完了です。今回使うメソッドはGETだけなんですが、CORSを有効にするにはOPTIONSメソッドが必要になります。
ハマった箇所
切り分けずに作業した結果、このエラーにハマりました。
sam validate時のエラーログ
Error: [InvalidResourceException(
'ApiGateway', "Unable to add Cors configuration because 'DefinitionBody' does not contain a valid Swagger")]
('ApiGateway', "Unable to add Cors configuration because 'DefinitionBody' does not contain a valid Swagger")
deploy 失敗時のcloud watchのログ
Unable to put integration response on 'OPTIONS' for resource at path '/weather_list':
Invalid mapping expression specified:
Validation Result: warnings :
[], errors :
[Invalid mapping expression specified: *]
(Service: AmazonApiGateway; Status Code: 400;
Error Code: BadRequestException; Request ID:
samをvalidateして調べて見た結果は、Swaggerが不適切、あるいは存在しない。
cloud watchのログでは、Apiで定義した weather_listのOPTIONS統合が不適切。
Swaggerの書き方が間違えているかと思い、swagger-cliでvalidateしながら項目を確認していきましたが、そこが原因ではなさそうです。
OPTIONS統合が不適切ということは、あらたに追加したCORSの設定とマッチしていないからなんでしょうが・・・。SwaggerとAPI GWは x-amazon-apigateway-integration というパラメータで結びついているようですが、どことどこが絡み合っているのかいまいちわかりません。そもそもSwaggerのエラーなのか、SAMのエラーなのか切り分けも難しいです。
その他
上のエラーでハマる以外にやっていたことです。
・code commitにアップロード + CI/CDについて調べる。code 3兄弟を使用してみることも考えたが、EC2をcode deployで使用するとお金がかかるので断念。(時間起動とかできそうですが、ec2の再起動にEBSが必要なのでもっとお金がかかりそう)
・pythonのコードの書き直し。お天気を取得するapiから、livedoorの都市名とお天気予報urlにアクセスして、予報のリストをとってくる方式に変更しました。
・jsにコードを追加
感想
おそらく、適当に動いていた時のコードをもってきて、見比べながら進めればできるのかな?という気がしています。Documentを読まないと、結局理解できなさそうなので、時間がある間はそのやり方で挑戦して見たいです。エラーから推測するやり方は今回試したので、samの拡張機能をキーワードに調べて見たいと思います。