Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

InputObjectType with different types of required #961

Closed
Glyphack opened this issue May 5, 2019 · 3 comments
Closed

InputObjectType with different types of required #961

Glyphack opened this issue May 5, 2019 · 3 comments
Labels

Comments

@Glyphack
Copy link

Glyphack commented May 5, 2019

Hi,
I faced this problem where I had an Update and Create mutations and that's how they work:
Create: Arguments is a graphene.InputObjectType where all of them are necessary and returns something
Update: Arguments is a graphene.InputObjectType where at least one of them is necessary and returns something
because I did not want to copy paste code like this

class CreateMutatation(graphene.Mutation):
    class Arguments:
        field1 = graphene.Int(required=True)
        field2 = graphene.Int(required=True)

class UpdateMutatation(graphene.Mutation):
    class Arguments:
        field1 = graphene.Int(required=False)
        field2 = graphene.Int(required=False)

I wanted a more cleaner version like this:

class Input(graphene.InputObjectType):
        field1 = graphene.Int()
        field2 = graphene.Int()

class CreateMutatation(graphene.Mutation):
    class Arguments:
        input = Input(required=all)

class UpdateMutatation(graphene.Mutation):
    class Arguments:
        input = Input(required=any)

I don't know if such thing exists but If I want to this I need a function to check if any of inputs is entered or not, is there a builtin way to this?

@ekampf ekampf added the question label May 6, 2019
@Glyphack Glyphack changed the title InputObjectType different types of required InputObjectType with different types of required May 7, 2019
@dvndrsn
Copy link
Contributor

dvndrsn commented May 15, 2019

Unfortunately, there isn't a clean way to do this in graphene (or any other library that defines a static schema through class attributes like attrs or django-rest-framework's Serializer).

An object like Input is used by Graphene to build a static schema for GraphQL. Having a static schema is super beneficial for tooling and API evolution purposes. The fact that a field is required (or optional) is part of that static schema. Meaning, if something is required on an object, it is required for all instances of that object. The only way to have a field required or not required in different contexts is to create a different object for each context.

Your Input example is simple enough that you might be annoyed to have some code duplication but just live with it. If you want to get creative, you might be able to apply metaprogramming to define a factory method to create these similar Input classes but with different name and value for required parameter.

def build_input(is_create=True):
    class Input(graphene.InputObjectType):
       class Meta:
           name=f'{prefix}StoryInput'

        title = graphene.String(required=is_create)
        author_name = graphene.String(required=is_create)

    return Input

CreateStoryInput = build_input(is_create=True)
StoryInput = build_input()

Generally, I would prefer to use a more repetitive, explicit implemention though. Good luck!

@nikordaris
Copy link
Contributor

nikordaris commented May 15, 2019

ya see Lee Byron's response to basically the same request in JS. graphql/graphql-js#207 (comment)

@jkimbo
Copy link
Member

jkimbo commented Jun 4, 2019

Closing this issue because (until this is defined in the GraphQL spec) it's not going to get implemented in Graphene (sorry 😞 )

@jkimbo jkimbo closed this as completed Jun 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

5 participants