如何在Rails中设置GraphQL Relay API

Car*_*nez 2 ruby-on-rails relay graphql

我试图围绕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宝石具有特定于文档中的一个部分继电器,但我发现很难理解设置此通过中继客户消费所需要的.

在Rails中为Relay客户端实现GraphQL API有什么必要?

Car*_*nez 15

我只想留下我的调查结果给那些在将来遇到这种情况并且想要指向更好方向的人.

首先,graphql-rubygem包含实现Relay兼容的GraphQL API所需的一切.In包括graphql-relaygem 中以前的所有内容.

您需要在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
Run Code Online (Sandbox Code Playgroud)

此外,所有类型都应该实现NodeInterfaceruby gem提供的,并公开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
Run Code Online (Sandbox Code Playgroud)

这将允许Relay重新获取如下数据:

query {
  node(id: "RmFjdGlvbjox") {
    id
    ... on Post {
      name
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Relay还使用了一个babel-relay-plugin需要schema.json生成并可供客户端使用的内容,如果你正在构建一个没有视图呈现的隔离API,那么就是让客户端获取模式而不是那样做在服务器中,像apollo-codegen这样的东西可以工作.但是,如果要构建rails应用程序并且需要同一应用程序中的架构,则可以运行instrospection查询并使用rake任务将结果保存到json文件:

Schema.execute GraphQL::Introspection::INTROSPECTION_QUERY
Run Code Online (Sandbox Code Playgroud)

最后,您需要了解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
Run Code Online (Sandbox Code Playgroud)

连接支持一些参数开箱即用,你可以使用first,last,beforeafter在你的连接查询:

query {
  posts(first: 5) {
    edges {
      node {
        name
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

所有这些都记录在Relay文档中,因此请确保您阅读它以及graphql-ruby文档.