シンプルすぎる実装ですがここまで来るのにけっこう時間かかったのでメモがてらに。
GraphQL
RESTに代わる問い合わせの仕様と理解しています。
こちらの記事がとてもわかりやすかったのでどうぞ↓
GraphQL入門 - 使いたくなるGraphQL
Hello, #{name}!
リクエストで名前を受け取って,JSONで Hello, hirapi!
文字列を返してみます。
使うのはこれ。
rmosolgo/graphql-ruby: Ruby implementation of GraphQL
免責(言い訳)
「とりあえず動かす」が目的で,設計がGraphQL APIの仕様として適切かと言われるとそうでもないです。
仕様は上記記事とか公式GraphQL Best Practices | GraphQLやGitHub GraphQL API | GitHub Developer Guideをご参照ください。
現実的にはidを受け取ってActiveRecordなりでレコード取得→結果をJSONで返す,という使い方になるかと思います。
そのとき返す形式もGraphQL::ObjectTypeとして定義できるみたいですが、そのあたりはこの記事では扱いません。
例外処理まわりもつけていません。適宜つけてください。
Gemfile
source 'http://rubygems.org'
ruby '2.4.0'
gem 'sinatra'
gem 'sinatra-contrib'
gem 'graphql'
main.rb
require 'graphql'
require 'sinatra'
require 'sinatra/json'
require 'sinatra/reloader'
register Sinatra::Reloader
configure do
QueryType = GraphQL::ObjectType.define do
name 'query'
field :hello do
type types.String # このクエリはStringを返す("Hello, hoge!")
argument :name, types.String # nameパラメータはStringで欲しい
resolve -> (obj, args, ctx) do
"Hello, #{args['name']}!" # DB等処理。クエリ内のパラメータは配列argsで受け取る
end
end
end
Schema = GraphQL::Schema.define do
query QueryType
end
end
post '/' do
req = JSON.parse(request.body.read)
query = <<-EOS # よくない実装
{
hello(name: "#{req['name']}")
}
EOS
Schema.execute(query).to_json
end
Ruby側でqueryを作ってますがリクエストが面倒くさくなるのが嫌だっただけです。
queryの通りのJSONをPOSTさせてそのまま Schema.execute(query)
に渡すべきですねw
挙動
実行してサーバー起動させて(sinatra便利)
[vagrant@app app_dir]$ ruby main.rb
== Sinatra (v2.0.0) has taken the stage on 4567 for development with backup from Puma
Puma starting in single mode...
* Version 3.8.2 (ruby 2.4.0-p0), codename: Sassy Salamander
* Min threads: 0, max threads: 16
* Environment: development
* Listening on tcp://localhost:4567
Use Ctrl-C to stop
リクエスト
curl -X POST -d '{"name": "hirapi"}' http://localhost:4567
レスポンス
{"data":{"hello":"Hello, hirapi!"}}
おわり。