我试图绕过GraphQL / Relay,我发现很难开始使用Ruby on Rails正确设置一个符合Relay标准的GraphQL API。
我找到了关于如何执行此操作的多个教程:
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
宝石,此刻似乎无法使用:https://github.com/rmosolgo/graphql-relay-ruby
grahql-ruby
gem在特定于relay的文档中有一个部分,但我发现很难理解将其设置为由中继客户端使用的内容。< / p>
在Rails中为Relay客户端实现GraphQL API有什么必要?
答案 0 :(得分:14)
我只想留下我的调查结果给那些在将来遇到这种情况并希望指向更好方向的人。
首先,graphql-ruby
gem包含实现Relay兼容GraphQL API所需的一切。 In包括graphql-relay
gem中以前的所有内容。
您需要在Schema中提供2项内容才能使Relay重新获取功能正常运行,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
这将允许Relay重新获取如下数据:
query {
node(id: "RmFjdGlvbjox") {
id
... on Post {
name
}
}
}
Relay还使用了一个babel-relay-plugin
,它需要生成一个schema.json并可供客户端使用,如果你要构建一个没有视图渲染的隔离API,那么就该采取行动。客户端获取模式而不是在服务器中执行该工作,apollo-codegen之类的工作可以正常工作。但是,如果要构建rails应用程序并且需要同一应用程序中的架构,则可以运行instrospection查询并使用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
Connections支持一些开箱即用的参数,您可以在连接查询中使用first
,last
,before
和after
:
query {
posts(first: 5) {
edges {
node {
name
}
}
}
}
Relay documentation中记录了所有这些内容,因此请务必仔细阅读graphql-ruby文档。
答案 1 :(得分:-2)
你试过安装吗?
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'