我只想把我的发现留在这里,以供将来遇到此问题并希望指出更好方向的任何人使用。
首先,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 应用程序并且需要在同一个应用程序中使用架构,那么您可以运行自省查询并使用 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 中,因此请务必阅读它以及 graphql-ruby 文档。