プロジェクトの作成
mkdir hanami-blog
cd hanami-blog
Gemfile
# frozen_string_literal: true
source "https://rubygems.org"
gem "hanami", '1.0.0'
bundle install
bundle exec hanami new . --application-name=api
bundle install
モデルの作成
bundle exec hanami generate model user
bundle exec hanami generate model post
20170621155700_create_users.rb
Hanami::Model.migration do
change do
create_table :users do
primary_key :id
column :name , String, null: false
column :email, String, null: false
column :created_at, DateTime, null: false
column :updated_at, DateTime, null: false
end
end
end
20170621155712_create_posts.rb
Hanami::Model.migration do
change do
create_table :posts do
primary_key :id
foreign_key :user_id, :users, on_delete: :cascade, null: false
column :title , String, null: false
column :content, String, null: true
column :created_at, DateTime, null: false
column :updated_at, DateTime, null: false
end
end
end
bundle exec hanami db prepare
Typeの作成
Gemfile
+ gem 'graphql', '1.6.4'
bundle install
mkdir -p apps/api/types
apps/api/application.rb
load_paths << [
'controllers',
'views',
+ 'types'
]
apps/api/types/user_type.rb
UserType = GraphQL::ObjectType.define do
name 'User'
description 'User'
field :id, types.ID
field :name, types.String
field :postss, types[!PostType]
end
apps/api/types/post_type.rb
PostType = GraphQL::ObjectType.define do
name 'Post'
description 'Post'
field :id , types.ID
field :title , types.String
field :content, types.String
field :user , UserType do
resolve ->(obj, _, _) { UserRepository.new.find(obj.user_id) }
end
end
apps/api/types/query_type.rb
require_relative 'user_type'
require_relative 'post_type'
QueryType = GraphQL::ObjectType.define do
name 'Query'
description 'The query root for this schema'
field :user do
type UserType
argument :id, !types.ID
resolve ->(_, args, _) { UserRepository.new.find(args[:id]) }
end
field :post do
type PostType
argument :id, !types.ID
resolve ->(_, args, _) { PostRepository.new.find(args[:id]) }
end
end
apps/api/types/hanami_blog_schema.rb
require_relative 'query_type'
HanamiBlogSchema = GraphQL::Schema.define(query: QueryType)
lib/hanami_blog/repositories/post_repository.rb
class PostRepository < Hanami::Repository
def posts_by_user(user)
posts.where(user_id: user.id)
end
end
Controllerの作成
apps/api/config/routes.rb
root to: "graphql#show"
apps/api/controllers/graphql/show.rb
module Api::Controllers::Graphql
class Show
include Api::Action
def call(params)
query_variables = params[:vairables] || {}
self.body = JSON.generate(HanamiBlogSchema.execute(params[:query], variables: query_variables))
end
end
end
テスト用データ作成
bundle exec hanami c
irb(main):002:0> user = UserRepository.new.create name: "foo", email: "foo@exsample.com"
irb(main):005:0> PostRepository.new.create user_id: user.id, title: "aaa", contest: "AAA"
irb(main):006:0> PostRepository.new.create user_id: user.id, title: "bbb", contest: "BBB"
試してみる
bundle exec hanami s
curl -XGET -d 'query={ user(id: 1) { name email posts {id title} } }' http://localhost:2300/ | jq .
{
"data": {
"user": {
"name": "foo",
"email": "foo@exsample.com",
"posts": [
{
"id": "1",
"title": "aaa"
},
{
"id": "2",
"title": "bbb"
}
]
}
}
}
curl -XGET -d 'query={ post(id: 1) { title user { name } } }' http://localhost:2300/ | jq .
{
"data": {
"post": {
"title": "aaa",
"user": {
"name": "foo"
}
}
}
}
以上。
Hanami x GraphQLのニッチ x ニッチでどこに需要があるのかって感じですが、なにかのご参考になれば。