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?
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!
ya see Lee Byron's response to basically the same request in JS. https://github.com/graphql/graphql-js/issues/207#issuecomment-243639236
Closing this issue because (until this is defined in the GraphQL spec) it's not going to get implemented in Graphene (sorry 馃槥 )
Most helpful comment
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
attrsordjango-rest-framework'sSerializer).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.
Generally, I would prefer to use a more repetitive, explicit implemention though. Good luck!