2017-02-11 4 views
1

Я пытаюсь обернуть голову вокруг GraphQL/Relay, и мне сложно начать правильно настраивать API-интерфейс, совместимый с реле, используя Ruby on Rails.Как настроить API ретрансляции GraphQL в Rails

Я нашел несколько учебников о том, как это сделать:

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 есть раздел в документации, относящейся к relay, но мне трудно найти убедитесь, что это необходимо для того, чтобы это было потреблено клиентом Relay.

Что необходимо для реализации API-интерфейса GraphQL для клиента Relay в Rails?

ответ

8

Я просто хочу, чтобы оставить здесь свои выводы для тех, кто застревает с этим в будущем, и хочет, чтобы указал на лучшую сторону.

Во-первых, драгоценный камень graphql-ruby включает в себя все, что необходимо для реализации совместимого с Relay API GraphQL. In включает в себя все, что было до этого в камне graphql-relay.

Вы должны предоставить 2 вещь в вашей схеме для того, чтобы сделать реле refetching функции, чтобы хорошо работать, в id_from_object метод, который преобразует объект в домене, в глобальную идентификатору, а также метод object_from_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 

Кроме того, все ваши типы должны осуществлять 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 

Это позволит Ретрансляция refetch такие данные:

query { 
    node(id: "RmFjdGlvbjox") { 
    id 
    ... on Post { 
     name 
    } 
    } 
} 

Реле также использует babel-relay-plugin, который требует schema.json быть создан и доступен для клиента, если вы строите изолированную API без вида рендеринг, путь - позволить клиентам получить схему и не выполнять эту работу на сервере, что-то вроде apollo-codegen может работать.Однако, если вы строите приложение рельсы и нуждаются в схеме в том же самом приложении, то вы можете запустить запрос instrospection и сохранить результат в файл JSON, используя грабли задачу:

Schema.execute GraphQL::Introspection::INTROSPECTION_QUERY 

Наконец, вы будете должны понимать, что реле выражает один-ко-многим с соединениями:

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.

0

Вы попробовали установить его?

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' 
+0

Да, это действительно работает, но использует старую версию 'graphql'. Я узнал, что «graphql-ruby» и «graphql-relay» были объединены. Я пытаюсь получить более удобное построение api, чтобы дать лучший ответ на этот вопрос, так как это определенно боль, чтобы начать с него –