如何在Rails

时间:2017-02-11 20:16:55

标签: ruby-on-rails graphql relay

我试图绕过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有什么必要?

2 个答案:

答案 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支持一些开箱即用的参数,您可以在连接查询中使用firstlastbeforeafter

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'