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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions