この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
おはようございます、もきゅりんです。
皆さん、API Gateway 使ってますか?
API Gateway といえば、 Lambda というくらいのセットイメージが一般的には強いと思うのですが、いろいろなサービスと関連付けることができますよね。
API の Gateway なのですから、APIを利用する側とAPIを提供する側の仲介、調整役として、 API Gateway は様々な機能を有しております。
ということで、本稿では REST API のHTTP統合を Swagger と Serverless Application Model (以下 SAM) でデプロイします。
実は大分前に、本稿を書いている途中、【初心者向け】SwaggerとAWS SAMを使ってWebAPIを簡単に作ってみた | DevelopersIO というグレートなブログを見つけて、あ、このブログいらないな、ということでそのままになっていました。
が、しばらくしてまた SAM を触る機会があったのですが、(普段あまり触らないので) あれ、サムってどんなんだったけ、とド忘れしてしまっていたため、自身の備忘録の意味もあり、まとめておくこととしました。
【初心者向け】SwaggerとAWS SAMを使ってWebAPIを簡単に作ってみた | DevelopersIO との構成の違いは下記になります。
- Cognito オーソライザーと連携する
- Lambda プロキシ統合ではなく、HTTP統合である
- CloudWatchLogs にログ出力する
構成図
API は Spring BootのREST APIをAWS Fargateにデプロイしてみた | DevelopersIO を再利用しています。
やること
- Cognito UserPool を作る
- SAMテンプレートを作る (Swaggerテンプレートも作る)
- デプロイする
- Postman で確認する
1 Cognito UserPool を作る
温かみある手動で Cognito UserPool は作成します。
基本的にデフォルト設定です。クライアントシークレットは解除、認証用の管理 API のユーザー名パスワード認証は有効にします。
手順は Cognitoで認証されたユーザーだけがAPI Gatewayを呼び出せるオーソライザーを使ってみた | DevelopersIO で丁寧にまとめられていますのでご参照下さい。
今回はIDトークンが欲しいだけなんです!
Cognito のサインイン時に発行されるトークンとそれらの役割についての詳細な説明は、Cognitoのサインイン時に取得できる、IDトークン・アクセストークン・更新トークンを理解する | DevelopersIO がとても分かりやすいです。
2 SAMテンプレートを作る
何はともあれ、 sam init
で開始します。
Getting started with AWS SAM - AWS Serverless Application Model を参考に SAM CLI を手に入れて、その使い方や作業の流れを、 Tutorial: Deploying a Hello World application - AWS Serverless Application Model を確認して進めます。
デフォルトテンプレートを AWS Serverless Application Model (AWS SAM) specification - AWS Serverless Application Model の仕様を参考に更新していって、ビルドしてデプロイします。
そんなこんなで、SAM テンプレートは以下になりました。
なお、 AWS SAMで「Stage」ステージが作られるバグを回避する に注意します。
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: demo-project
Globals:
Api:
OpenApiVersion: 3.0.2
Resources:
ApiGatewayLogs:
Type: AWS::Logs::LogGroup
Properties:
LogGroupName: /demo/sam-rest-api
RetentionInDays: 30
ApiGatewayApi:
Type: AWS::Serverless::Api
Properties:
StageName: dev
AccessLogSetting:
DestinationArn: !GetAtt ApiGatewayLogs.Arn
Format: $context.identity.sourceIp $context.identity.caller \
$context.identity.user [$context.requestTime] \
"$context.httpMethod $context.resourcePath $context.protocol" \
$context.status $context.responseLength $context.requestId
EndpointConfiguration: REGIONAL
Name: sam-rest-api
Auth:
Authorizers:
cognitoAuth:
UserPoolArn: arn:aws:cognito-idp:reagion:account-id:userpool/reagion_cognito_id
DefaultAuthorizer: cognitoAuth
InvokeRole: CALLER_CREDENTIALS
DefinitionBody:
Fn::Transform:
Name: AWS::Include
Parameters:
Location: ./swagger.yml
MethodSettings:
- DataTraceEnabled: true
LoggingLevel: INFO
ResourcePath: '/*'
HttpMethod: '*'
Outputs:
HelloWorldApi:
Description: API Gateway endpoint URL for Prod stage for Hello World function
Value:
Fn::Sub: https://${ApiGatewayApi}.execute-api.${AWS::Region}.amazonaws.com/dev/greeting/
Swagger を使ってドキュメントを作る
OpenAPI (Swagger) 超入門 - Qiita とかを参考に Swagger Editor, Swagger UI, Swagger Codegen など好きなもので作ります。
この辺は身近な API 職人にアドバイス貰うと良いでしょう。(アドバイス貰いたい...)
なお、API Gateway 独自の仕様があるので、手元の Swagger ファイルをそのまま使えるわけではない可能性もあるので、注意が必要です。
詳細は、OpenAPI への API Gateway 拡張機能の使用 - Amazon API Gateway をご参照下さい。
自分が頑張って作ったのが以下です。
openapi: 3.0.1
info:
title: Sample Hello API
version: 1.0.0
servers:
- url: /
paths:
/greeting:
get:
description: Return Hello
responses:
200:
description: 200 response
content: {}
x-amazon-apigateway-integration:
responses:
default:
statusCode: "200"
uri: http://xxxxxxxxxxxxxxxxx.ap-northeast-1.elb.amazonaws.com/greeting
passthroughBehavior: when_no_match
httpMethod: GET
type: http
頑張ったけど、ドキュメントを眺めながら気合で頑張るよりも、最初に手で自由に設定した後に API Gateway から REST API をエクスポートする - Amazon API Gateway を参考にエクスポートしちゃった方が効率的だと思いました。
## sample export command
aws apigateway get-export --parameters extensions='apigateway' --rest-api-id abcdefg123 --stage-name dev --export-type swagger latestswagger2.json
APIを起動する
Spring BootのREST APIをAWS Fargateにデプロイしてみた | DevelopersIO を参考にAPIを起動させておきます。
デプロイする
AWS CLIがAWS::Include transformをS3へアップロードできるようになりました | DevelopersIO を参考に AWS::Include transform を使ってS3へSwaggerテンプレートをアップロードしてデプロイします。
## バケットがなければ適当にバケットを作成します
aws s3 mb s3://everyday-sam-bucket
aws cloudformation package \
--s3-bucket everyday-sam-bucket \
--template-file sam.yml \
--output-template-file template.yml
Uploading to 002d01928360fe5180926ecbf91836a4 588 / 588.0 (100.00%)
Successfully packaged artifacts and wrote output template to file template.yml.
Execute the following command to deploy the packaged template
aws cloudformation deploy --template-file <YOUR PATH>/template.yml --stack-name <YOUR STACK NAME>
言われるがままコマンド叩きます。
aws cloudformation deploy --template-file <YOUR PATH>/template.yml --stack-name <YOUR STACK NAME>
確認
IDトークンを取得します。
aws cognito-idp admin-initiate-auth \
--user-pool-id <YOUR USER POOL ID> \
--client-id <YOUR APP CLIENT ID> \
--auth-flow ADMIN_NO_SRP_AUTH \
--auth-parameters USERNAME=<YOUR USERNAME>,PASSWORD=<YOUR PASSWORD>
REST API のテストツールは何を使っても良いと思いますが、Postman を使用して REST API を呼び出す - Amazon API Gateway を参考に、 Postman を使って見てみると下記のような結果となりました。
問題ないようですね。
以上です。
最後に
またしばらく SAM を触らない間に忘れないように雰囲気まとめておきました。
ついでに、どなたかのお役に立つことがあれば幸いです。