Search code examples
djangographqlgraphene-djangographene2

Graphene-django with generic resolver to return List or Field


I am trying to simplify my graphene-django view to have a single graphene query that returns a graphene.List or a graphene.Field based on whether a parameter was sent.

I am attempting the following code, but I am not sure how to handle the change between a List and Field response;

    """ 
        graphene.Field & graphene.List will not be determined until the resolver 'resolve_employee' 
        checks if a employeeId param is sent.

        Issue : How can I make this generic to return a list or a field
    """


    employee = graphene.Field(EmployeeType, employeeId=graphene.Int())

    def resolve_employee(self, info, **kwargs):
        employeeId = kwargs.get('employeeId')
        if employeeId is not None:
            return Employee.objects.get(pk=employeeId)
        else:
            return Employee.objects.all()

This is my current schema.py with two separate

class EmployeeType(DjangoObjectType):
    class Meta:
        model = Employee


class Query(object):)
    allEmployees = graphene.List(EmployeeType, active=graphene.Boolean())
    employeeDetail = graphene.Field(EmployeeType, employeeId=graphene.Int())

        
    def resolve_allEmployees(self, info, **kwargs):
        active_param = kwargs.get('active')
        if type(active_param) == bool:
            return Employee.objects.filter(term_date__isnull=active_param)
        return Employee.objects.all()


    def resolve_employeeDetail(self, info, **kwargs):
        employeeId = kwargs.get('employeeId')
        if employeeId is not None:
            return Employee.objects.get(pk=employeeId)

Solution

  • Having an output format that switches on a parameter doesn't fit the spirit of graphQL. However, you could solve your problem by keeping the same output format by using employeeId as a filter and returning the output as a list. For example:

    def resolve_Employees(self, info, **kwargs):
        active_param = kwargs.get('active')
        employee_id = kwargs.get('employeeId')
        employees = Employees.objects.all()
        if type(active_param) == bool:
            employees = employees.filter(term_date__isnull=active_param)
        if employee_id:
            employees =  employees.filter(id=employee_id)  # filter list to just one employee
        return employees