如何在 Rails 中设置 GraphQL 中继 API
How to setup a GraphQL Relay API in Rails
我正在努力思考 GraphQL/Relay,但我发现很难开始了解如何使用 Ruby 在 Rails.
我找到了多个关于如何执行此操作的教程:
https://medium.com/react-weekly/relay-facebook-on-rails-8b4af2057152#.gd8p6tbwi
https://medium.com/@gauravtiwari/graphql-and-relay-on-rails-getting-started-955a49d251de#.m05xjvi82
但是他们都指的是 graphql-relay
gem 目前似乎不可用:https://github.com/rmosolgo/graphql-relay-ruby
grahql-ruby
gem 在文档中有一个特定于 relay 的部分,但我发现很难理解将其设置为由中继客户端。
在 Rails 中为 Relay 客户端实现 GraphQL API 需要什么?
你试过安装吗?
vagrant$ bundle install
Fetching gem metadata from https://rubygems.org/............
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies...
Installing graphql 0.19.4
Using bundler 1.11.2
Installing graphql-relay 0.12.0
Bundle complete! 1 Gemfile dependency, 3 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
在 Gemfile 中:
gem 'graphql-relay'
我只想将我的发现留在这里,以供将来遇到此问题并希望指明更好方向的任何人。
首先,graphql-ruby
gem 包含实现 Relay 兼容 GraphQL API 所需的一切。其中包括 graphql-relay
gem.
之前的所有内容
您需要在 Schema 中提供 2 个东西才能使 Relay refetching 功能正常工作,一个 id_from_object
将域中的对象转换为全局 ID 的方法,以及一个 object_from_id
将全局 ID 解码为应用程序中对象的方法:
ApplicationSchema = GraphQL::Schema.define do
/* Create IDs by joining the type name & ID, then base64-encoding it */
id_from_object ->(object, type_definition, query_ctx) {
GraphQL::Schema::UniqueWithinType.encode(type_definition.name, object.id)
}
object_from_id ->(id, query_ctx) {
type_name, object_id = GraphQL::Schema::UniqueWithinType.decode(id)
# Now, based on `type_name` and `id`
# find an object in your application
# This will give the user access to all records in your db
# so you might want to restrict this properly
Object.const_get(type_name).find(object_id)
}
end
此外,您的所有类型都应实现 ruby gem 提供的 NodeInterface
,并公开 global_id_field
而不是 ID 类型:
PostType = GraphQL::ObjectType.define do
name "Post"
# Implements the "Node" interface for Relay
interfaces [GraphQL::Relay::Node.interface]
# exposes the global id
global_id_field :id
field :name, types.String
end
这将允许中继像这样重新获取数据:
query {
node(id: "RmFjdGlvbjox") {
id
... on Post {
name
}
}
}
Relay 还使用了一个 babel-relay-plugin
,它需要生成一个 schema.json 并可供客户端使用,如果你正在构建一个没有视图渲染的孤立 API,那么要走的是让客户端获取架构而不是在服务器中执行该工作,例如 apollo-codegen 可以工作。但是,如果您正在构建一个 rails 应用程序并需要同一应用程序中的模式,那么您可以 运行 一个内省查询并使用 rake 任务将结果保存到一个 json 文件:
Schema.execute GraphQL::Introspection::INTROSPECTION_QUERY
最后,你需要了解 Relay 表示一对多的连接关系:
PostType = GraphQL::ObjectType.define do
# default connection
# obj.comments by default
connection :comments, CommentType.connection_type
# custom connection
connection :featured_comments, CommentType.connection_type do
resolve ->(post, args, ctx) {
comments = post.comments.featured
if args[:since]
comments = comments.where("created_at >= ?", since)
end
comments
}
end
end
连接支持一些开箱即用的参数,您可以在连接查询中使用 first
、last
、before
和 after
:
query {
posts(first: 5) {
edges {
node {
name
}
}
}
}
所有这些都记录在 Relay documentation so make sure you read it as well as the graphql-ruby 文档中。
我正在努力思考 GraphQL/Relay,但我发现很难开始了解如何使用 Ruby 在 Rails.
我找到了多个关于如何执行此操作的教程:
https://medium.com/react-weekly/relay-facebook-on-rails-8b4af2057152#.gd8p6tbwi
https://medium.com/@gauravtiwari/graphql-and-relay-on-rails-getting-started-955a49d251de#.m05xjvi82
但是他们都指的是 graphql-relay
gem 目前似乎不可用:https://github.com/rmosolgo/graphql-relay-ruby
grahql-ruby
gem 在文档中有一个特定于 relay 的部分,但我发现很难理解将其设置为由中继客户端。
在 Rails 中为 Relay 客户端实现 GraphQL API 需要什么?
你试过安装吗?
vagrant$ bundle install
Fetching gem metadata from https://rubygems.org/............
Fetching version metadata from https://rubygems.org/...
Fetching dependency metadata from https://rubygems.org/..
Resolving dependencies...
Installing graphql 0.19.4
Using bundler 1.11.2
Installing graphql-relay 0.12.0
Bundle complete! 1 Gemfile dependency, 3 gems now installed.
Use `bundle show [gemname]` to see where a bundled gem is installed.
在 Gemfile 中:
gem 'graphql-relay'
我只想将我的发现留在这里,以供将来遇到此问题并希望指明更好方向的任何人。
首先,graphql-ruby
gem 包含实现 Relay 兼容 GraphQL API 所需的一切。其中包括 graphql-relay
gem.
您需要在 Schema 中提供 2 个东西才能使 Relay refetching 功能正常工作,一个 id_from_object
将域中的对象转换为全局 ID 的方法,以及一个 object_from_id
将全局 ID 解码为应用程序中对象的方法:
ApplicationSchema = GraphQL::Schema.define do
/* Create IDs by joining the type name & ID, then base64-encoding it */
id_from_object ->(object, type_definition, query_ctx) {
GraphQL::Schema::UniqueWithinType.encode(type_definition.name, object.id)
}
object_from_id ->(id, query_ctx) {
type_name, object_id = GraphQL::Schema::UniqueWithinType.decode(id)
# Now, based on `type_name` and `id`
# find an object in your application
# This will give the user access to all records in your db
# so you might want to restrict this properly
Object.const_get(type_name).find(object_id)
}
end
此外,您的所有类型都应实现 ruby gem 提供的 NodeInterface
,并公开 global_id_field
而不是 ID 类型:
PostType = GraphQL::ObjectType.define do
name "Post"
# Implements the "Node" interface for Relay
interfaces [GraphQL::Relay::Node.interface]
# exposes the global id
global_id_field :id
field :name, types.String
end
这将允许中继像这样重新获取数据:
query {
node(id: "RmFjdGlvbjox") {
id
... on Post {
name
}
}
}
Relay 还使用了一个 babel-relay-plugin
,它需要生成一个 schema.json 并可供客户端使用,如果你正在构建一个没有视图渲染的孤立 API,那么要走的是让客户端获取架构而不是在服务器中执行该工作,例如 apollo-codegen 可以工作。但是,如果您正在构建一个 rails 应用程序并需要同一应用程序中的模式,那么您可以 运行 一个内省查询并使用 rake 任务将结果保存到一个 json 文件:
Schema.execute GraphQL::Introspection::INTROSPECTION_QUERY
最后,你需要了解 Relay 表示一对多的连接关系:
PostType = GraphQL::ObjectType.define do
# default connection
# obj.comments by default
connection :comments, CommentType.connection_type
# custom connection
connection :featured_comments, CommentType.connection_type do
resolve ->(post, args, ctx) {
comments = post.comments.featured
if args[:since]
comments = comments.where("created_at >= ?", since)
end
comments
}
end
end
连接支持一些开箱即用的参数,您可以在连接查询中使用 first
、last
、before
和 after
:
query {
posts(first: 5) {
edges {
node {
name
}
}
}
}
所有这些都记录在 Relay documentation so make sure you read it as well as the graphql-ruby 文档中。