Graphene-django: How to match a resolver to a Node.Field

Created on 3 Nov 2017  路  8Comments  路  Source: graphql-python/graphene-django

Not sure if the best place for this issue is here or at graphene repo (https://github.com/graphql-python/graphene), but here we go ...

I have a Node.Field that I want to match to a resolver in order to apply token authentication/authorization. But it seems the resolver is completely ignored. Here is a code sample:

from graphene_django.types import DjangoObjectType
from graphene_django.filter import DjangoFilterConnectionField
from graphene import ObjectType, Node, String

from core.utils import validate_token

from .models import Paciente


class PacienteType(DjangoObjectType):

    class Meta:
        model = Paciente
        interfaces = (Node, )
        filter_fields = ['id', 'nome']


class Query(ObjectType):

    paciente = Node.Field(PacienteType, id=String(), token=String())
    paciente_all = DjangoFilterConnectionField(PacienteType, token=String())

    def resolve_paciente(self, info, id=None, token=None):
        usuario_id = validate_token(token)
        if usuario_id is None:
            return None

        try:
            return Paciente.objects.get(pk=id)
        except:
            return None

    def resolve_paciente_all(self, info, token=None):
        usuario_id = validate_token(token)
        if usuario_id is None:
            return []
        return Paciente.objects.all()

Then I issue the following query

{
    paciente(id: "UGFjaWVudGVUeXBlOjE=") {
      id
    }
}

Which I expected to be blank, since I'm not supplying any auth token, but it does return with one result. Am I missing something here that I have not seem, or this may be a bug?

Thanks!

wontfix

Most helpful comment

Try this, instead of:

paciente = Node.Field(PacienteType, id=String(), token=String())

do:

paciente = graphene.Field(PacienteType, id=String(), token=String())

or simply:

paciente = graphene.Field(PacienteType)

The documentation is non existent, and examples are very inconsistent, lack descriptions, lack the "why's", versions mixed, relay vs non-relay confused, etc. Looks like nobody is really in charge of this project so get ready for trial and error unfortunately.

All 8 comments

can you try printing in resolve_paciente to see if it is being ran?

I did place a pdb.set_trace() (python's debugger), and in fact it wasn't being called/stopped at all.

Try this, instead of:

paciente = Node.Field(PacienteType, id=String(), token=String())

do:

paciente = graphene.Field(PacienteType, id=String(), token=String())

or simply:

paciente = graphene.Field(PacienteType)

The documentation is non existent, and examples are very inconsistent, lack descriptions, lack the "why's", versions mixed, relay vs non-relay confused, etc. Looks like nobody is really in charge of this project so get ready for trial and error unfortunately.

to resolve a global id, inside a normal field do
relay.Node.get_node_from_global_id(info, id)

@vinigfer

If you want to implement something like token authentication, you probably want it outside of each individual resolver. I would suggest subclassing GraphQLView with django's LoginRequiredMixin (as seen here, and then adding the token authentication as one of your django authentication methods.

Some time passed however i had the same kind of problem and have found kind of solution.
Everything works fine while resolving DjangoFilterConnectionField. In cases of graphene.relay.Node.Field, resolver as vingifer said above is being ignored.

What I have done to work with it is: changing graphene.relay.Node.Field back to graphene.Field (no relay format). Resolver works, I just needed to work inside about understanding the relay format ID.

If somone has better solution I would appreciate as well. We all here know that some complications around graphene and relay exist ;)

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

to resolve a global id, inside a normal field do
relay.Node.get_node_from_global_id(info, id)

I wish I knew how this worked, really is like magic to me

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dan-klasson picture dan-klasson  路  4Comments

Dawidpol picture Dawidpol  路  4Comments

MythicManiac picture MythicManiac  路  3Comments

BrianChapman picture BrianChapman  路  3Comments

amiyatulu picture amiyatulu  路  3Comments