serverlessフレームワークでGraphQLのエンドポイントを提供する実例、serverless-graphql-blogを触ってみた
先日2016/2/1、serverlessからこういう記事が出てました。
Serverless GraphQL - Kevin Old | Full-Stack JavaScript Engineer | React.js | Node.js
From conception of the idea of Serverless GraphQL a few weeks ago, to the reference implementation of Serverless GraphQL Blog I have spent less than $1 on AWS resources and only a few hours implementing.
serverless-graphql-blog
なる、serverlessフレームワーク上でGraphQLを用いたブログシステムを作ったから見てみなよ!とのことです。
どんなん?
まずserverless
とは、AWS Lambda
と AWS API Gateway
を利用してサーバレスでスケールしやすいエンドポイントを作れるフレームワークです。github上で6,000個以上スターが付いています。
今回のserverless-graphql-blog
は、その上でGraphQLを提供する実例のようなもの(reference implementation
と言っているようだが)です。
先述のこの記事で詳しく紹介されてる。
(私には)早すぎた
で、動かすにあたり、NodeもLambdaも大初心者の私がハマりましたので以下に記録しておきます(2016/2/7)。
Node大初心者なので間違っている部分は多々あると思いますので、そっと教えて下さい、。。
各バージョンとか
- OSX:
10.10.3
$ node -v; npm -v v5.4.1 3.3.12
$ npm list | grep serv serverless-graphql-blog@0.0.1 /[省略]/serverless-graphql-blog ├─┬ serverless-helpers-js@0.0.3 └─┬ serverless-optimizer-plugin@1.0.0
動いた手順とか試行錯誤過程
gitで言うとこのへんのバージョンのREADMEを読みました。
読んだところ、以下の手順でやればよさ気な感じです。
$ npm install serverless -g
$ serverless project install serverless-graphql-blog
$ serverless dash deploy
以下適宜メモを入れていきます。
$ npm install serverless -g
グローバルにserverlessパッケージが入ります。 これは特にハマりませんでした。
$ serverless project install serverless-graphql-blog
カレントディレクトリの下にserverless-graphql-blog
が展開されます。
展開されたあとに 以下のかっこいい感じ でウィザードが始まります。
$ serverless project install serverless-graphql-blog Serverless: Installing Serverless Project "serverless-graphql-blog"... Serverless: Downloading project and installing dependencies... _______ __ | _ .-----.----.--.--.-----.----| .-----.-----.-----. | |___| -__| _| | | -__| _| | -__|__ --|__ --| |____ |_____|__| \___/|_____|__| |__|_____|_____|_____| | | | The Serverless Application Framework | | serverless.com, v0.3.1 `-------' Serverless: Initializing Serverless Project...
いろいろ対話的に聞かれますので入力していく。
Serverless: Enter a universally unique project bucket name: (serverless-graphql-blog-ae1ue6-gutlvy.com) Serverless: Enter an email to use for AWS alarms: (me@serverless-graphql-blog-ae1ue6.com) Serverless: Enter the ACCESS KEY ID for your Admin AWS IAM User: Serverless: Enter the SECRET ACCESS KEY for your Admin AWS IAM User:
Lambda functionなどを配置するバケット、アラーム用のEmailの設定、 AWSのアクセスキー、AWSのSECRET ACCESS KEYなどを入力します。
~/.aws/credentials
にファイルが在る人は、アクセスキー等に関してはそのプロファイルが使われるかもしれません。
serverlessのドキュメント内のベストプラクティスを読むと、
「AdministratorAccess
を持つユーザの情報を与えるべきでなく、最大でもPowerUserAccess
にしてください」とのことでした。
今回私はPowerUserAccessポリシーを持つユーザを一時的に作り、キー等を入力しました。
Serverless: Select a region for your project: > us-east-1 us-west-2 eu-west-1 ap-northeast-1
次にリージョンですが、ap-northeast-1
(東京)が選択できるのですが、東京だとなぜかS3のバケット作成に失敗する( バケットの文字数制限に引っかかってる気がする… )ので、
us-east-1
(バージニア北部)を選択しました。
Serverless: Creating stage "dev"... Serverless: Creating region "us-east-1" in stage "dev"... Serverless: Creating your project bucket on S3: serverless.us-east-1.serverless-graphql-blog-ae1ue6-gutlvy.com... Serverless: Deploying resources to stage "dev" in region "us-east-1" via Cloudformation (~3 minutes)...
ここまで問題なくうまくいくと、 Cloud Formationが走ります。
Cloud Formationと言うと、一気にオオゴト感が増した気がしますが、気にしない方向で行きましょう。
$ serverless dash deploy
次に上記のコマンドですが、これは$ cd serverless-graphql-blog
してからじゃないと動きません。
そのへんは空気嫁という感じでしょうか、、
$ serverless dash deploy _______ __ | _ .-----.----.--.--.-----.----| .-----.-----.-----. | |___| -__| _| | | -__| _| | -__|__ --|__ --| |____ |_____|__| \___/|_____|__| |__|_____|_____|_____| | | | The Serverless Application Framework | | serverless.com, v0.3.1 `-------' Use the <up>, <down>, <pageup>, <pagedown>, <home>, and <end> keys to navigate. Press <enter> to select/deselect, or <space> to select/deselect and move down. Press <ctrl> + <enter> to immediately deploy selected. Serverless: Select the assets you wish to deploy: blog - resource - graphql function - blog/resource/graphql endpoint - blog/resource/graphql@resource/graphql~POST - - - - - > Deploy Serverless: Deploying functions in "dev" to the following regions: us-east-1 Serverless: ------------------------ Serverless: Successfully deployed functions in "dev" to the following regions: Serverless: us-east-1 ------------------------ Serverless: blog/resource/graphql: arn:aws:lambda:us-east-1:70000000000:function:serverless-graphql-blog-blog-resource-graphql:dev Serverless: Deploying endpoints in "dev" to the following regions: us-east-1 Serverless: Successfully deployed endpoints in "dev" to the following regions: Serverless: us-east-1 ------------------------ Serverless: POST - resource/graphql - https://xxxxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/resource/graphql
実行して成功した場合は上記のような出力となります。途中でfunction
とendpoint
どちらを(または両方を)デプロイするか、ということを選択できます。
ここでは以下の点にハマりました。
_meta/variables/s-variables-dev-useast1.json
に追加の情報が必要
blog/resource/graphql: Missing required key 'Role' in params
という謎のエラーが出てしまいます。
似たような事象を参考に解決しました。
_meta/variables/s-variables-dev-useast1.json
の中身を変えればいいようです。以下のように編集した。
before
{ "region": "us-east-1" }
after
{ "region": "us-east-1", "apiGatewayApi": "serverless-graphql-blog", "iamRoleArnLambda": "arn:aws:iam::7000000000:role/lambda_basic_execution" }
arn...lambda_basic_execution
の部分は適当にIAMでlambda用のロールを作っておきます。
今回はLambda君がDynamoに触れるようにする必要があります。以下の様なポリシーでいけました。過不足ないかは未確認。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "Resource": "arn:aws:logs:*:*:*" }, { "Sid": "Stmt1428000000017", "Action": [ "dynamodb:DeleteItem", "dynamodb:GetItem", "dynamodb:PutItem", "dynamodb:Query", "dynamodb:Scan", "dynamodb:UpdateItem" ], "Effect": "Allow", "Resource": "*" } ] }
モジュールをnpm installする必要あった
以上でデプロイ完了です。
ので、curlすればレスポンスが返ってくるのですが、
{"errorMessage":"Cannot find module 'serverless-helpers-js'","errorType":"Error"...
とかいうエラーメッセージが返ってきてしまいます。どうやら必要なmoduleがLambdaの中に入れられていないようでした。
このへん、Herokuとかの感覚でやるとうまくいかないものですね。。。
--- a/package.json +++ b/package.json @@ -12,7 +12,10 @@ "dependencies": { "babel-preset-es2015": "^6.3.13", "babelify": "^7.2.0", - "serverless-optimizer-plugin": "^1.0.0" + "graphql": "^0.4.16", + "graphql-custom-types": "^0.2.0", + "serverless-optimizer-plugin": "^1.0.0", + "serverless-helpers-js": "^0.0.3" }, "description": "A Serverless GraphQL blog.", "devDependencies": {},
バージョンがこれでいいのかはわかりませんが、こうやっておいて npm i
し、deployすると動きました。
これでいいんだろうか。
とりあえずおわり!
あとはREADMEに書いてあるようなcurlコマンドで、GraphQLを楽しむことが出来ます。
例:
DynamoDB上のauthorsテーブル:
クエリ投げる/返ってくる:
$ curl -s -XPOST -d '{"query": "{ authors { id, name } }"}' \ https://randamunamoji.execute-api.us-east-1.amazonaws.com/dev/resource/graphql | jq . { "data": { "authors": [ { "id": "2", "name": "mitsuo" }, { "id": "1", "name": "senda" } ] } }
まとめ
今の時代、一家に一台、フルスタックnodeエンジニア がいれば、サーバレスで高可用なGraphQLエンドポイントが簡単に手に入るようです。