graphql-рубиновый. Используйте (не реле) мутации СУХОЙ. С или без GraphQL::Function?
Я НЕ ИСПОЛЬЗУЮ РЕЛЕ.
Я прочитал несколько уроков. Многие используют этот способ для мутаций:
Приложение /graphql/graphql_tutorial_schema.rb
GraphqlTutorialSchema = GraphQL::Schema.define do
query(Types::QueryType)
mutation(Types::MutationType)
end
приложение / graphql / резольверы /create_link.rb
class Resolvers::CreateLink < GraphQL::Function
argument :description, !types.String
argument :url, !types.String
type Types::LinkType
def call(_obj, args, _ctx)
Link.create!(
description: args[:description],
url: args[:url],
)
end
end
и наконец они имеют:
Приложение / graphql / типы /mutation_type.rb
Types::MutationType = GraphQL::ObjectType.define do
name 'Mutation'
field :createLink, function: Resolvers::CreateLink.new
end
Таким образом, они используют GraphQL::Function
,
Это путь? Если я не использую ретранслятор, это единственный путь?
А что, если я хочу уникальный файл для всех link
операции (CRUD)?
Другие руководства ( http://tech.eshaiju.in/blog/2017/05/15/graphql-mutation-query-implementation-ruby-on-rails/) используют это:
Приложение / graphql / мутации /comment_mutations.rb
module CommentMutations
Create = GraphQL::Relay::Mutation.define do
name "AddComment"
# Define input parameters
input_field :articleId, !types.ID
input_field :userId, !types.ID
input_field :comment, !types.String
# Define return parameters
return_field :article, ArticleType
return_field :errors, types.String
resolve ->(object, inputs, ctx) {
article = Article.find_by_id(inputs[:articleId])
return { errors: 'Article not found' } if article.nil?
comments = article.comments
new_comment = comments.build(user_id: inputs[:userId], comment: inputs[:comment])
if new_comment.save
{ article: article }
else
{ errors: new_comment.errors.to_a }
end
}
end
end
и app/graphql/mutations/mutation_type.rb
MutationType = GraphQL::ObjectType.define do
name "Mutation"
# Add the mutation's derived field to the mutation type
field :addComment, field: CommentMutations::Create.field
end
поэтому я могу добавить также:
MutationType = GraphQL::ObjectType.define do
name "Mutation"
field :addComment, field: CommentMutations::Create.field
field :updateComment, field: CommentMutations::Update.field
field :deleteComment, field: CommentMutations::Delete.field
end
Но это хорошо работает только с Create = GraphQL::Relay::Mutation.define
: Я не использую реле!
В ваших документах я не нашел ничего, связанного с этой проблемой.
Я должен всегда использовать GraphQL:: Функции?
Или, может быть, я могу использовать это так:
MutationType = GraphQL::ObjectType.define do
name "Mutation"
field :addComment, field: CommentMutations::Create
field :updateComment, field: CommentMutations::Update
field :deleteComment, field: CommentMutations::Delete
end
и иметь это (код является примером):
module Mutations::commentMutations
Createcomment = GraphQL::ObjectType.define do
name "Createcomment"
input_field :author_id, !types.ID
input_field :post_id, !types.ID
return_field :comment, Types::commentType
return_field :errors, types.String
resolve ->(obj, inputs, ctx) {
comment = comment.new(
author_id: inputs[:author_id],
post_id: inputs[:post_id]
)
if comment.save
{ comment: comment }
else
{ errors: comment.errors.to_a }
end
}
end
Updatecomment = GraphQL::ObjectType.define do
name "Updatecomment"
input_field :author_id, !types.ID
input_field :post_id, !types.ID
return_field :comment, Types::commentType
return_field :errors, types.String
resolve ->(obj, inputs, ctx) {
comment = comment.new(
author_id: inputs[:author_id],
post_id: inputs[:post_id]
)
if comment.update
{ comment: comment }
else
{ errors: comment.errors.to_a }
end
}
end
end
Это другой способ?
2 ответа
Вам следует попробовать https://github.com/samesystem/graphql_rails gem. Он имеет структуру MVC на стороне graphql, поэтому ваш GraphQL будет почти таким же, как ваш код RoR.
А что, если мне нужен уникальный файл для всех операций со ссылками (CRUD)?
В GraphqlRails вместо преобразователей есть контроллеры. У вас могло быть что-то вроде этого:
class CommentsController < GraphqlRails::Controller
action(:create).permit(:article_id, :body).returns(!Types::CommentType)
action(:update).permit(:id, :body).returns(!Types::CommentType)
def create
Comment.create!(params)
end
def update
Comment.find(params[:id]).update!(params)
end
end
Вот как сейчас выглядит моя:
blah_schema.rb
BlahSchema = GraphQL::Schema.define do
...
query(Types::QueryType)
mutation_type.rb
Types::MutationType = GraphQL::ObjectType.define do
name "Mutation"
field :comment, !Types::CommentType do
argument :resource_type, !types.String
argument :resource_id, !types.ID
argument :comment, !types.String
resolve ResolverErrorHandler.new ->(obj, args, ctx) do
ctx[:current_user].comments.
create!(resource_id: args[:resource_id],
resource_type: args[:resource_type],
comment: args[:comment])
end
end
field :destroy_comment, !Types::CommentType do
argument :id, !types.ID
resolve ResolverErrorHandler.new ->(obj, args, ctx) do
comment = ctx[:current_user].comments.where(id: args[:id]).first
if !comment
raise ActiveRecord::RecordNotFound.new(
"couldn't find comment for id #{args[:id]} belonging to #{current_user.id}")
end
comment.destroy!
comment
end
end
end
resolver_error_handler.rb
class ResolverErrorHandler
def initialize(resolver)
@r = resolver
end
def call(obj, args, ctx)
@r.call(obj, args, ctx)
rescue ActiveRecord::RecordNotFound => e
GraphQL::ExecutionError.new("Missing Record: #{e.message}")
rescue AuthorizationError => e
GraphQL::ExecutionError.new("sign in required")
rescue ActiveRecord::RecordInvalid => e
# return a GraphQL error with validation details
messages = e.record.errors.full_messages.join("\n")
GraphQL::ExecutionError.new("Validation failed: #{messages}")
rescue StandardError => e
# handle all other errors
Rails.logger.error "graphql exception caught: #{e} \n#{e.backtrace.join("\n")}"
Raven.capture_exception(e)
GraphQL::ExecutionError.new("Unexpected error!")
end
end
Так что да, это другое - я не уверен, что это лучше, это просто то, что я придумал. Мой mutation_type.rb намного толще, что мне не нравится.
Вы не четко сформулировали какие-либо цели или проблемы, чтобы помочь вам получить более конкретный ответ.
Есть еще один метод, который я использовал недавно. Мы также не используем React, и было странно использовать GraphQL::Relay::Mutation.define
для описания мутаций.
Вместо этого мы опишем fields
, (например: app/graphql/mutations/create_owner.rb
)
Mutations::CreateOwner = GraphQL::Field.define do
name 'CreateOwner'
type Types::OwnerType
description 'Update owner attributes'
argument :name, !types.String
argument :description, types.String
resolve ->(_obj, args, _ctx) do
Owner.create!(args.to_h)
end
end
Тогда в вашем app/graphql/types/mutation_type.rb
вы добавляете:
field :createOwner, Mutations::CreateOwner
Это может быть изменено в дальнейшем путем извлечения распознавателей в их собственные классы распознавателей.
Без определенных передовых методов, которые мне удалось обнаружить, это был довольно чистый способ решения этой проблемы.