当前位置: 首页 > 工具软件 > graphql-faker > 使用案例 >

rails graphql的使用

薛扬
2023-12-01

1.graphql的基本概念

  • GraphQL 是一种针对 Graph(图状数据)进行查询特别有优势的 Query Language(查询语言),所以叫做 GraphQL。
  • 它跟 SQL 的关系是共用 QL 后缀,就好像「汉语」和「英语」共用后缀一样,但他们本质上是不同的语言。
  • GraphQL 并没有和任何特定数据库或者存储引擎绑定,而是依靠你现有的代码和数据支撑。
  • 向你的 API 发出一个 GraphQL 请求就能准确获得你想要的数据,不多不少

2.graphql的组成部分

  • Fields: 是关于请求对象上的特定字段
  • Arguments:请求时传递的参数以及它们是什么对象类型, 这是必需的。这有点类似于在Rails控制器中定义强参数,这里对进入的内容进行更细粒度的控制。
  • Types: 类型,用于定义数据类型,或者定义Rails模型model,类型包括根据-Queries/Mutations中的请求相应数据的字段和函数。类型也可以是静态的,比如:String或ID,这些内置在服务器端的library中。
  • Queries:从API获取特定的数据。将查询设置为只读,就像Rest里面的Get,但是查询不仅是Get。
  • Mutations: 变更,对API数据的修改,比如:create、update、destroy。
  • Resolver解析器:resolve方法是执行ActiveRecord命令的地方。他返回一个带有和上面定义的字段名称一样的键的hash.
  • Functions: 方法、功能,给上面的字段提供数据,

3.创建一个基于graphql的rails项目

step1:创建一个rails 项目,并生成对应的model**

  • 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

step2: 引入gem包

  • gem ‘faker’
  • gem ‘graphiql-rails’

step3:在user.rb里面加入 has_many :books

在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

step4: 创建graphql目录和2个新的自定义类型User和Post

  • rails g graphql:install
  • rails g graphql:object user
  • rails g graphql:object post

step5: 在routes.rb中,创建app/controllers/graphql_controller.rb#execute,作为api访问的入口

 if Rails.env.development?
    mount GraphiQL::Rails::Engine, at: '/graphql', graphql_path:"graphql#execute"
  end

启动项目,访问http://localhost:3000/graphiql,就可以看到测试api接口的页面

step6: 创建GraphQL的类型(Type)

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

step7: 定义主查询类型

query_type.rb和mutation_type.rb这两种传入请求的路由,定义在模式schema里面,他们和Rails路由和资源有些相似。分别为查询和修改特定的数据

    class GraphqlApiSchema < GraphQL::Schema
      mutation(Types::MutationType)
      query(Types::QueryType)
    end

step8: 在query_type文件里面,定义:users和:user的字段,以及他们的方法

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

step9: 测试查询

  • 查询所有用户信息
query{
  users{
    id
    name
    email
    postsCount
  }
}
  • 查询指定id的用户信息
 query{
  user(id:2){
    id
    name
    email
    postsCount
  }
}

step10: Mutations(变更 )

Mutations允许创建、修改、销毁数据,我们设置一个基类,用来扩展CreateUser的mutation。

module Mutations
  class BaseMutation < GraphQL::Schema::RelayClassicMutation
  end
end

step11: 创建CreateUser的mutation。

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

step12: 将新变更mutation添加到主突变类型类中,以便暴露给我们的API。

module Types
  class MutationType < Types::BaseObject
    field :create_user, mutation: Mutations::CreateUser
  end
end

step13 创建用户测试

我们传入一个createUser(input: {})对象; 这映射到:create_user接受单个input参数的字段。

mutation{
  createUser(input:{
    name:"张三",
    email:"aa@qq.com"
  }){
    user{
      id
      name
      email
    }
    errors
  }
}
 类似资料: