APIGateway の MappingTemplate
※CURLでテストすると勝手に「Content-Type: application/x-www-form-urlencoded」がつけられるのでちゃんと自分でヘッダーを指定しましょう。
MappingTemplateが正常に動作するようになったらこんなエラーが返ってくるようになった。
{"message": "Could not parse request body into json: Unexpected character (\',\' (code 44)): expected a valid value (number, String, array, object, \'true\', \'false\' or \'null\')\n at [Source: [B@6812cadd; line: 4, column: 16]"}
指定したMappingTemplateはこんな感じ。
#set($inputRoot = $input.path('$')) { "type": "$inputRoot.type", "address": "$inputRoot.address", "location": $inputRoot.location, "title": "$inputRoot.title", "description": "$inputRoot.description" }
「$inputRoot.location」がnullの時とかにJSONとしてフォーマットがおかしくなるからこんなエラーが返ってくる。
一旦こんな形式にしてみたけども
#set($inputRoot = $input.path('$')) { "type": "$inputRoot.type", "address": "$inputRoot.address", "location": { "lat": $inputRoot.location.lat, "lon": $inputRoot.location.lon }, "title": "$inputRoot.title", "description": "$inputRoot.description" }
これでも「$inputRoot.location.lat」がnullの時にNG。
でもここは数値にしたいから""でも囲うこともできない。
そうするとここでわざわざ#ifとかでnullの時は設定しないー的なことをする必要があるってこと?
だったらもうソース側でやればよくね?
いまいちよくわからん。
serverless での エラーマッピングの仕方。
そもそものエラーの返し方はこちら。
return context.done(new Error("invalid type :" + type ));
レスポンスコードを変えたりしたい時は、 s-function.json の responses をいじる 。
こんな感じでコンソール上の「Lambda Error Regex」を「selectionPattern」に 設定する。
デフォルトだとstackTraceがそのまま出てしまうのでテンプレートを設定している。
"responses": { "400": { "statusCode": "400", "selectionPattern": "invalid type.*", "responseTemplates": { "application/json": "#set($inputRoot = $input.path('$'))\n{\n \"errorMessage\": \"$inputRoot.errorMessage\",\n \"errorType\": \"$inputRoot.errorType\"#if($context.stage == \"development\"),\n \"stackTrace\": $inputRoot.stackTrace#end\n\n}" } },
テンプレートを見やすく整形するとこんな感じ。
stageでstackTraceの出力を切り替えている。
#set($inputRoot = $input.path('$')) { "errorMessage": "$inputRoot.errorMessage", "errorType": "$inputRoot.errorType"#if($context.stage == "development"), "stackTrace": $inputRoot.stackTrace #end }
serverlessのs-function.jsonに設定する値
この辺を見ながらやる感じ? docs.aws.amazon.com
serverlessのmappingtemplateのフォーマットメモ
responseTemplatesのforeachとかは、ここの記述フォーマットに従っている。
Apache Velocity - VTL Reference
jsonのフィールドの先頭に「_」があった時にうまくテンプレートに適用できなかった。
そんな時はここを見るといい感じ。
serverless はまった
serverlessはnode v4以上必須なのだが
lambdaのnodeはv0.10なので
classとか使うと怒られます。
ローカルのテストの意味が。。。ねぇ!!
serverlessで一つのfunctionをrunする方法
公式ドキュメントには
sls function run myModule/myFunctions#functionOne
って書いてあるけど実際にそれでやっても
Serverless: Select a function to run: myFunctions > functionOne functionTwo
ってなっちゃうのでもやもやしてた。
こう書いたら選択しなくてもテストできるのですな。
sls function run -n functionOne
serverless さわってみた
所感
serverless (旧名JAWS)の使い勝手を調べてみた。
結果としては割といい感じ。
serverlessならansibleとかもいらなくなる!
AWSのリソースもserverlessの中のCloudFormationでOKだぜ!!みたいな。。?
まだまだドキュメントは少ないけど、もうちょっと勉強していこうと思う。。
手順
初期セットアップ
※Node 4系以上が必要
$ sudo npm install serverless -g
$ mkdir ~/.aws
$ vi ~/.aws/credentials
--
[default]
aws_access_key_id=<<アクセスキー>>
aws_secret_access_key=<<シークレットアクセスキー>>
--
$ vi ~/.aws/config
--
[default]
region = ap-northeast-1
--
作ってみる
$ serverless project create
_______ __
| _ .-----.----.--.--.-----.----| .-----.-----.-----.
| |___| -__| _| | | -__| _| | -__|__ --|__ --|
|____ |_____|__| \___/|_____|__| |__|_____|_____|_____|
| | | The Serverless Application Framework
| | serverless.com, v.0.0.12
`-------'
Serverless: Enter a project name: (serverlessN1A2rULrx) akira-test
Serverless: Enter a project domain (used for serverless regional bucket names): (myapp.com) akira-test.com
Serverless: Enter an email to use for AWS alarms: (me@myapp.com)
Serverless: Select a region for your project:
us-east-1
us-west-2
eu-west-1
> ap-northeast-1
Serverless: Select an AWS profile for your project:
> default
Serverless: Creating a project region bucket on S3: serverless.apnortheast1.akira-test.com...
Serverless: Creating CloudFormation Stack for your new project (~5 mins)...
Serverless: Successfully created project: akira-test
- 作られたもの
- S3
- IAM Group
- IAM Role
- ディレクトリ構成
-rw-r--r-- 1 arika staff 11 12 13 21:38 README.md
-rw-r--r-- 1 arika staff 136 12 13 21:38 admin.env
drwxr-xr-x 4 arika staff 136 12 13 21:38 back
drwxr-xr-x 3 arika staff 102 12 13 21:38 cloudformation
drwxr-xr-x 2 arika staff 68 12 13 21:38 plugins
-rw-r--r-- 1 arika staff 495 12 13 21:41 s-project.json
CloudFormationでIAMあたりを作っているっぽ。S3は別。
CloudFormationのテンプレートが自動生成されて、そこにIAMのロールやらの定義が書かれている。
んで、おそらくここにAWS elsaticsearchの設定とかを書いておいてserverless resources deploy
ってやるとデプロイされる、とかができるための仕組みだと思う。
AWSのリソースの管理もできるということですね。素晴らしい。
モジュールとかファンクションとかを作る
$ serverless module create -m greetings -f hello
Serverless: Successfully created hello function.
Serverless: Installing "serverless-helpers" for this module via NPM...
serverless-helpers-js@0.0.3 node_modules/serverless-helpers-js
└── dotenv@1.2.0
Serverless: Successfully created new serverless module "greetings" with its first function "hello"
$ ls -l back/modules/greetings/
total 16
drwxr-xr-x 5 arika staff 170 12 13 21:49 hello
drwxr-xr-x 3 arika staff 102 12 13 21:49 lib
drwxr-xr-x 3 arika staff 102 12 13 21:49 node_modules
drwxr-xr-x 2 arika staff 68 12 13 21:49 package
-rw-r--r-- 1 arika staff 359 12 13 21:49 package.json
-rw-r--r-- 1 arika staff 277 12 13 21:49 s-module.json
backっていうディレクトリの下にhelloっていうのができて、
そこのhandler.jsってやつがメイン処理っぽい。。。?
'use strict';
/**
* Serverless Module: Lambda Handler
* - Your lambda functions should be a thin wrapper around your own separate
* modules, to keep your code testable, reusable and AWS independent
* - 'serverless-helpers-js' module is required for Serverless ENV var support. Hopefully, AWS will add ENV support to Lambda soon :)
*/
// Require Serverless ENV vars
var ServerlessHelpers = require('serverless-helpers-js').loadEnv();
// Require Logic
var lib = require('../lib');
// Lambda Handler
module.exports.handler = function(event, context) {
lib.respond(event, function(error, response) {
return context.done(error, response);
});
};
...いや、こっちか?でもlibの下にメイン処理があるもんか?
おそらくhandlerはいじらずここだけ意識していじればいいぜって感じか?
/**
* Lib
*/
module.exports.respond = function(event, cb) {
var response = {
message: "Your Serverless function ran successfully!"
};
return cb(null, response);
};
lambdaへのデプロイ
$ serverless function deploy
Serverless: Deploying functions in "development" to the following regions: ap-northeast-1
Serverless: Successfully deployed functions in "development" to the following regions: ap-northeast-1
api gatewayへのデプロイ
$ serverless endpoint deploy
Serverless: Deploying endpoints in "development" to the following regions: ap-northeast-1
Serverless: Successfully deployed endpoints in "development" to the following regions:
Serverless: ap-northeast-1 ------------------------
Serverless: GET - https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/development/greetings/hello
ローカルでのテスト
ローカルでのテストも簡単にできるのは素晴らしい。
$ serverless function run
Serverless: Running GreetingsHello...
Serverless: -----------------
Serverless: Success! - This Response Was Returned:
Serverless: {"message":"Your Serverless function ran successfully!"}
リンク集
http://docs.serverless.com/v0/docs
http://qiita.com/mokemokechicken/items/f81c886053f7d81a655d