Rails Ruby on Rails 使用 GraphQL 例子

xfstart07 · 2017年06月01日 · 最后由 TommyLemon 回复于 2018年07月18日 · 10140 次阅读
本帖已被管理员设置为精华贴

英语翻译的不好,我把基本的介绍和操作步骤整理了。项目中一共有 4 个例子。分别放在四个 Tags 中。有查询、修改、嵌套数据查询,N+1 问题的解决。

介绍

GraphQL 是一个接口搜索语言,由 Feacbook 在 2015 年开源的。

GraphQL 就是可以让客户端查询他们确切需要的数据,服务器并不会有过多的返回。

一个 GraphQL 请求分为 查询 (读操作),或 变化 (mutation,写操作), 请求是一个简单的字符串 (类似 json 的格式),GraphQL 服务能解析,执行,并返回指定的数据。

GraphQL 主要特点

  • 在请求中,只返回客户端需要的数据

  • 在一次请求中,返回更多资源。

  • 用类型系统描述什么是可得的

  • 可维护性 - 不需要考虑版本的迭代 API

GraphQL 查询例子

一个查询用户的例子

{
  user(id: 1) {
    firstName,
    lastName,
    email
  }
}

结果

{
  "data": {
    "user": {
      "firstName": "Shaiju",
      "lastName": "E",
      "email": "[email protected]"
     }
   }
}

在 Rails 中搭建 GraphQL 服务

添加 Gem

# Gemfile
gem "graphql"
gem 'graphiql-rails', group: :development

graphiql-rails 是一个 graphql 的 Web 请求页面,使用 graphiql 打包成一个 Gem.

然后执行 bundle install

生成 GraphQL 文件

rails g graphql:install

生成:

  • 创建一个文件夹 app/graphql/
  • 创建一个默认的 schema
  • 添加一个查询类型定义
  • 添加一个查询路由

运行查看

rails server
open localhost:3000/graphiql

增加一个文章查询 (article)

增加一个文章类型 ArticleType

ArticleType = GraphQL::ObjectType.define do
  name "Article"
  field :id, types.Int
  field :title, types.String
  field :body, types.String
  field :comments, types[CommentType]
end

然后建立一个查询模式

路径 app/graphql/types/query_type.rb

QueryType = GraphQL::ObjectType.define do
  name "Query"
  description "一个根查询的 schema"

  field :acticle do
    type ArticleType
    argument :id, !types.ID
    description "Find a Article by ID"
    resolve ->(obj, args, ctx) { Article.find_by_id(args["id"]) }
  end
end

schema 进入文件

路径 app/graphql/graphq_api_schema.rb

GraphqApiSchema = GraphQL::Schema.define do
  query(Types::QueryType)
end

application.rb 中加载 graphql 文件

config.autoload_paths << Rails.root.join('app/graphql')
config.autoload_paths << Rails.root.join('app/graphql/types')

下面启动 rails, 在 localhost:3000/graphiql 查询文章

query {
  acticle(id: 1){
    title
  }
}

结果

{
  "data": {
    "acticle": {
      "title": "A GraphQL Server"
    }
  }
}

也可以通过 execute 命令查询

query_string = "
{
  acticle(id: 1) {
    id
    title
  }
}"
result_hash = GraphqApiSchema.execute(query_string)

# output:
# {
#   "data" => {
#     "acticle" => {
#        "id" => 1,
#        "title" => "A GraphQL Server"
#     }
#   }
# }

Resource

http://graphql-ruby.org/

https://github.com/xfstart07/graphql-api

http://tech.eshaiju.in/blog/2017/05/06/a-graphql-server-implementation-ruby-on-rails/

huacnlee 将本帖设为了精华贴。 06月01日 10:10

最近准备试试 GraphQL

@kevinzhow 在 Twitter 上看到你好像在写 Go,Go 也支持 GraphQL 的,http://graphql.org/code/#go 其实我还没在正式项目上使用过,但 GraphQL 真的挺不错的,特别是对于前端来说有更多的选择权,不用经常讨论字段少了或者多了

xfstart07 回复

嗯,准备找个服务试试

最近在项目上用上 graphql 了,感觉 graphql-ruby 已经比较完善,用起来没遇到什么较大的问题。而且 graphql 是支持自省的,因此生成文档很方便,假如前端熟悉 graphql 的话甚至不需要文档。所以就不用担心文档忘了更新的情况了。要说缺点的话,目前我觉得最大的问题就是 Graphql 的过于复杂,非常多的定义,从啃文档到开始实现花了我两天多的时间😂 。我认为这也是 graphql 并不怎么火的原因,后端去定义一套 Schema 需要理解 Graphql 大部分定义,否则用起来可能还没直接写 API 方便。(PS:之前也用过API expand的方式去提升接口灵活性,但一方面自己开发还是比较花时间的,另外灵活性也比不上 graphql,所以比起来我认为 graphql 更好)

写得很简洁,不错👍

@hfpp2012 谢谢😀

@ACzero 确实 GraphQL 有很多自定义的东西,熟悉了应该写起来就快很多了。毕竟定义都是固定的,剩下的还是使用 Ruby 写的逻辑了

准备考虑一下

很棒,虽然我看不懂,但我会持续学习~😁 😁

真及时,刚好开始看这个东西赞

vry nyc 1

分享个 GraphQL 在线的 demo: http://blx.rubyfans.com

性能如何,支持 swaager 不

目前用了一个月 GraphQL 了,感觉是方便了前端吧…后端感觉还是效率不是太好,特别是当前端为了能一条查询得到所有数据,嵌套了太多层之后,岂止是 N+1,简直要 (N+1)^2。为了把这些 N+1 消灭掉,着实要花一些功夫。 总而言之还是对前端方便了许多,后端则变得麻烦了,此消彼长的感觉。

使用 GraphQL,如果客户端需要的数据很多,每次请求接口都要拼好多字段,这样岂不是很麻烦?

sapphire 回复

@sapphire @hegwin @tangmonk

完爆 Facebook/GraphQL,APIJSON 全方位对比解析 (三)-表关联查询 https://my.oschina.net/tommylemon/blog/1857762

完爆 Facebook/GraphQL,APIJSON 全方位对比解析 (二)-权限控制 https://juejin.im/post/5b13cda1f265da6e4a6bcfee

完爆 Facebook/GraphQL,APIJSON 全方位对比解析 (一)-基础功能 https://juejin.im/post/5ae80edd51882567277433cf

需要 登录 后方可回复, 如果你还没有账号请 注册新账号