rails new graphql_fun_demo
rails g model User email:string name:string
rails g model Post user:belongs_to title:string body:text
rails db:migrate
在seeds.rb文件,通过faker创建一些数据
5.times do
user = User.create(name: Faker::Name.name, email: Faker::Internet.email)
5.times do
user.posts.create(title: Faker::Lorem.sentence(word_count: 3),
body: Faker::Lorem.paragraph(sentence_count: 3))
end
end
rails g graphql:install
rails g graphql:object user
rails g graphql:object post
if Rails.env.development?
mount GraphiQL::Rails::Engine, at: '/graphql', graphql_path:"graphql#execute"
end
启动项目,访问http://localhost:3000/graphiql,就可以看到测试api接口的页面
module Types
class UserType < Types::BaseObject
# null: false 不允许为空
field :id, ID, null: false
field :name, String, null: true
field :email, String, null: true
field :posts, Types::PostType, null: true
field :posts_count, Integer, null: true
def posts_count
object.posts.size
end
end
end
module Types
class PostType < Types::BaseObject
field :id, ID, null: false
field :user_id, Integer, null: true
field :title, String, null: true
field :body, String, null: true
end
end
query_type.rb和mutation_type.rb这两种传入请求的路由,定义在模式schema里面,他们和Rails路由和资源有些相似。分别为查询和修改特定的数据
class GraphqlApiSchema < GraphQL::Schema
mutation(Types::MutationType)
query(Types::QueryType)
end
module Types
class QueryType < Types::BaseObject
field :users, [Types::UserType], null: false
# users方法返回UserType类型的一组对象。
def users
User.all
end
# user方法接收一个类型为ID的:id的参数,返回一个UserType对象,(ID是一个内置的类型)
field :user, Types::UserType, null: false do
argument :id, ID, required: true
end
def user(id:)
User.find(id)
end
end
end
query{
users{
id
name
email
postsCount
}
}
query{
user(id:2){
id
name
email
postsCount
}
}
Mutations允许创建、修改、销毁数据,我们设置一个基类,用来扩展CreateUser的mutation。
module Mutations
class BaseMutation < GraphQL::Schema::RelayClassicMutation
end
end
class Mutations::CreateUser < Mutations::BaseMutation
argument :name, String, required: true
argument :email, String, required: true
# 和上面查询字段概念相同,接收参数创建对象,同时希望返回一个user带有我们的新模型的字段,并附带一个errors数组。
field :user, Types::UserType, null: false
field :errors, [String], null: false
def resolve(name:, email:)
user = User.new(name: name, email: email)
if user.save
{
user: user,
errors: [],
}
else
{
user: nil,
errors: user.errors.full_message
}
end
end
end
module Types
class MutationType < Types::BaseObject
field :create_user, mutation: Mutations::CreateUser
end
end
我们传入一个createUser(input: {})对象; 这映射到:create_user接受单个input参数的字段。
mutation{
createUser(input:{
name:"张三",
email:"aa@qq.com"
}){
user{
id
name
email
}
errors
}
}