8000 Help with constructing an arbitrary ObjectType · Issue #699 · graphql-python/graphene · GitHub
[go: up one dir, main page]

Skip to content

Help with constructing an arbitrary ObjectType #699

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

Closed
jchang10 opened this issue Mar 27, 2018 · 4 comments
Closed

Help with constructing an arbitrary ObjectType #699

jchang10 opened this issue Mar 27, 2018 · 4 comments

Comments

@jchang10
Copy link
jchang10 commented Mar 27, 2018

Hi, I am still just learning. Looking for advice on an issue.

The simple question is, what is the best way to instantiate an ObjectType?

Here is a longer drawn out explanation for a simple question. I currently have something like below that returns a UserObjectType. Everything is great and user field resolves correctly. Returns the UserObjectType that is initialized by 'some_init_dictionary' which graphql takes care of on backend somewhere.

class NotesType(ObjectType):
    user = graphene.Field(UserObjectType)

    def resolve_user(self, args, context, info):
        return some_init_dictionary

Looking at examples, I decided I want to get fancy with Interfaces. Basically, I am trying to copy the example schema for StarWars and define the user field as a UserInterface. Then return an instance of UserObjectType.

class NotesType(ObjectType):
    user = graphene.Field(UserInterface)

    def resolve_user(self, args, context, info):
        return UserObjectType(**some_init_dictionary)

I simply replaced UserObjectType with UserInterface. That all works fine, too.

However, if some_init_dictionary has an extra field, then I get the "is an invalid keyword argument" error. In the original with UserObjectType, the extra field is ignored and everything merrily works fine.

Thus, am I missing something here? I would rather not have to do something like:

return UserObjectType(arg1='arg1', arg2='arg2', ... etc.)

and explicity call the constructor with each argument and field. I just want to duplicate how graphql handles the instantiation of UserObjectType as in the original version.

I hope that made sense. This should be a fairly simple answer/question. Thank you!

Jae

@jchang10
Copy link
Author
jchang10 commented Mar 29, 2018

To answer my own question, I had to make sure to define a classmethod on UserObjectType named is_type_of(cls, value,context,info) to return a bool value on whether to accept the "returned data type" that your custom code returns from the resolver for your ObjectType.

See

super(ObjectType, cls).__init_subclass_with_meta__(_meta=_meta, **options)
is_type_of = None
def __init__(self, *args, **kwargs):

It's too bad there isn't better documentation. We have to rely on the code. However, the code isnt even really commented much, like the line above.

@jkimbo
Copy link
Member
jkimbo commented Apr 4, 2018

@jchang10 another approach to resolving interface types is to define a (undocumented) classmethod resolve_type(cls, instance, info) method on the interface. This allows you to resolve the concrete type given some data. So in your example:

class UserInterface(graphene.Interface):
	@classmethod
	def resolve_type(cls, data, info):
		if data['type'] == 'human':
			return Human
		return Droid

Then your NotesType would just return the some_init_dictionary in the resolver and (given it has a type attribute`) it would resolve to the correct concrete type. e.g.:

class NotesType(ObjectType):
    user = graphene.Field(UserInterface)

    def resolve_user(self, args, context, info):
        return some_init_dictionary

I've found this very useful when implementing interfaces.

@jchang10
Copy link
Author
jchang10 commented May 1, 2018

Cool. Just saw this. Thanks for the update!

@tony
Copy link
tony commented Nov 26, 2018

@jkimbo Has this changed since this issue has been posted? (I'm playing with this example code right now and it's not working. It seems the resolve_type on the interface is never executed. I will try to come up with a minimal example)

(Edit) Potentially related: #775

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants
0