【问题标题】:How to setup a GraphQL Relay API in Rails如何在 Rails 中设置 GraphQL Relay API
【发布时间】:2017-06-30 01:31:03
【问题描述】:

我正试图围绕 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 的 gem,目前似乎不可用:https://github.com/rmosolgo/graphql-relay-ruby

grahql-ruby gem 在文档中有一个特定于relay 的部分,但我发现很难理解需要什么来设置它以供 Relay 客户端使用。

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

【问题讨论】:

    标签: ruby-on-rails graphql relay


    【解决方案1】:

    你试过安装吗?

    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。我发现graphql-rubygraphql-relay 被合并了。我正在尝试更轻松地构建 api 以更好地回答这个问题,因为开始使用它绝对是一种痛苦
    【解决方案2】:

    我只想把我的发现留在这里,以供将来遇到此问题并希望指出更好方向的任何人使用。

    首先,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
    

    连接支持一些开箱即用的参数,您可以在连接查询中使用firstlastbeforeafter

    query {
      posts(first: 5) {
        edges {
          node {
            name
          }
        }
      }
    }
    

    所有这些都记录在 Relay documentation 中,因此请务必阅读它以及 graphql-ruby 文档。

    【讨论】:

      猜你喜欢
      • 2016-02-10
      • 1970-01-01
      • 2016-07-26
      • 2018-01-16
      • 2016-11-02
      • 2018-02-12
      • 2015-11-20
      • 2021-01-11
      • 2016-10-28
      相关资源
      最近更新 更多