Skip to content

Override graphql_name to allow for shared mutations #225

@TomasBarry

Description

@TomasBarry

What is the problem the enhancement will solve?

In our system, we have multiple different resources. We would like to have a single mutation per operation that can be shared between the various resources.

Essentially, be able to use a Union Type for the authenticable resource where all resources can share a common mutation rather than having to implement one mutation per resource per operation.

Describe the solution you have in mind

Allow for the overriding of graphql_name in a custom mutation that inherits from one of the GraphQLDevise operations:

module Mutations
  # A single login mutation that can be used to log in any resource
  class ResourceLogin < GraphqlDevise::Mutations::Login
    # A union type representing the Authenticable types (those types that can
    # be logged in). This allows for us to have a single login mutation rather
    # than one mutation per resource. We can use the mutation as:
    #
    # mutation {
    #   resourceLogin(
    #     email: "email@domain.com",
    #     password: "some_password"
    #   ) {
    #     authenticatable {
    #       ... on ResourceA {
    #         id
    #       }
    #     }
    #   }
    # }
    class Authenticable < Types::BaseUnion
      description 'An authenticatable resource'
      possible_types(
        Types::ResourceAType,
        Types::ResourceBType
      )

      def self.resolve_type(object, _context)
        case object
        when ResourceA then Types::ResourceAType
        when ResourceB then Types::ResourceBType
        else raise GraphQL::ExecutionError, "Unhandled Authenticable #{object.class}"
        end
      end
    end

    graphql_name 'resource_login'

    field :authenticatable, Authenticable, null: false

    def resolve(email:, password:)
      super do |resource|
        # custom behaviour
      end
    end
  end
end

Then the schema file can mount resources like:

GraphqlDevise::ResourceLoader.new(
  ResourceA,
  only: [
    :login
  ],
  operations: {
    login: Mutations::ResourceLogin
  }
),
GraphqlDevise::ResourceLoader.new(
  ResourceB,
  only: [
    :login
  ],
  operations: {
    login: Mutations::ResourceLogin
  }
)

Describe alternatives you've considered

One mutation per resource.

Additional context

It seems that there is no customisation of the mutation name available in https://github.com/graphql-devise/graphql_devise/blob/v0.18.2/lib/graphql_devise/mount_method/operation_preparers/default_operation_preparer.rb

It appears that the above ignores any custom graphql_name setting in a mutation linked to an operation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions