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エンドポイントが簡単に手に入るようです。
【Go初心者】麻雀のあがり判定をRubyで書いたやつをGoで書きなおしてみた、そして多少のvimrc追加
天和あがれるやつをGoで書きなおしてみました。
処理速度は超早くなりました。当社比2000%。
成長の記録(のびしろですね!)。
Go書くのは人生初です。
CもJavaも書いたことなくて、rubyしか書いたことないのですが、
forとifさえあればなんとかなるという感じでやった。後悔はしていない。
インターフェースとか書けるのが嬉しいらしいっぽい、時間あるときに学びたい。
以下、初心者がGoはじめるにあたり環境周りでやったことなど。
vim周り1
golang vimrc
でググッて適当に調べただけで、べんりなものがあった。
.vimrc
へ以下を追記。
事前にnsf/gocodeをgo getしておく。
+ +" http://qiita.com/uchiko/items/4c186292f007535116cc +filetype off +filetype plugin indent off +" set runtimepath+=$GOROOT/misc/vim +filetype plugin indent on +syntax on +autocmd FileType go autocmd BufWritePre <buffer> Fmt +exe "set rtp+=".globpath($GOPATH, "src/github.com/nsf/gocode/vim") +set completeopt=menu,preview
vim周り2
golangといえばハードタブ。
私のvimrcではC-iはソフトタブが挿入されちゃう感じだったので、拡張子で判断できるように変更。
+ +" http://blog.restartr.com/2014/04/20/vimrc-noexpandtab-in-golang/ +if expand("%:t") =~ ".*\.go" + set noexpandtab + set tabstop=4 + set shiftwidth=4 +endif
以上2つの変更で、:w
で保存した時に自動的にgo fmt的なのが走る感じになる。
go、pythonなんて比じゃないぐらい固い言語という印象を持った。
Go書けるようになりたい!
いまのところまだよくわかってないところ箇条書き:
- なぞの「interface」
- ダックタイピングできるらしい
- なぞの「goroutine」
- 並列処理書きたい
- テスト
- テストフレームワークがないのはわかった、どういう感じで書くのがいいんだろう
次は七対子解決と七対子以外解決をゴルーチンで並列処理するという野望を持っています
— 俺がJOINだ (@hoppiestar) 2016, 1月 3
麻雀のあがり判定をゼロから書いて、天和コマンドを作ってみた
【車輪】麻雀のあがり判定をゼロから書いて、天和コマンドを作ってみた感想【再発明】
プログラミングの話ですが、麻雀の話です。
$ tenho
ってコマンドを打つと天和がアガれたら面白いんじゃないかと思って、作った
うごくやつができた
こんなん
なぜそんなことを
ruby -e "puts '🀀'.next" => "🀁"
みたいに文字が使えるし、CLIでも見栄えが良いかなと思ってた。
休日の車輪の再発明にはちょうど良さそう。
ロジックの方はおみくじ感覚でかんたんにできるかなと思ってた。
が、あがり判定っていうのはわりと難易度高かった。。
ロジックとか感想とか
以降、だらだらと感想とか書く。
$ tenho
の動き自体は、
- (34 * 4)のカード(牌)の束からランダムに14枚を取り出す。
- それがアガっていれば終了。上がっていなければもう一度14枚取り出す
という感じ。
ランダムに14枚取り出すのはArray#sample
的なものが使った(あ、rubyっす)。
やはりあがり判定がキーになる。
適当に書いた感じでも、1秒間に1500回以上のサンプリングとあがり判定ができたっぽい。意外と速くて満足してしまった : )。
それでも感覚的には天和上がるには200万回ぐらい必要(本当の確率は調べてない。。)なので、数分必要なのだが。。
自分が書く上でポイントだと思ったこと3つ。
3つのあがり系
周知の通り麻雀には3つのあがり形があって(すくなくとも天和の場合はこの3つでいいと思う)
というかんじになる。ここに気づくのがポイント。
スート
スート(トランプでいうところのハート・ダイヤ・クラブ・スペード)が4種類(萬・筒・索・字)。
字牌だけは、順子が作れないという特徴がある。
別のスート同士で順子や刻子や対子は構成できないので、必然的にカードをスート毎にグルーピングする必要が出てくる。
テスト書きながら書くと楽
こういうときのテストは書いてて楽しい
書きながら思ったこと
七対子だるいwwwww
七対子をどこで判定するかがだるい。
たとえば索子が8枚あるということがわかっているとき、それは(3+3+2)形でなかったとしても(2+2+2+2)形かもしれない。
七対子の判定の順序は、最初のほうにしたほうがパフォーマンスが良いかもしれない。
順子と刻子
順子と刻子の判定については難しいかなと思ってたら、そうでもなかった。
三連刻のかたち(444555666とか)の判定は、役を解釈しないかぎり(天和だけを考慮する場合)は気にしなくて良いので。
同様に役を解釈しないかぎりにおいては、七対子か二盃口か、みたいな判定も要らない。
今後書きたいこと
書いてると無性にオプション作りたくなる。いま思いついたのは以下。センス☓。
--[no-]normal
ノーマル型(33332型)を除外--[no-]chi-toitsu
七対子を除外--[no-]kokushi
国士無双を除外--limit [arg]
リミットを指定--sanma
サンマモード
あと他の言語で書いても面白いかもしれないと思ってる