Lambda queries refuse to returns null for 'name' field

It seems that a lambda resolver cannot return a field called name. I’ve tested this using multiple types just to be sure it’s not working.

Here’s an example query:

query {
  queryRole {
     id
     name
   }
}
  • Running this as a normal query works just fine
  • Running this as a lambda query (or mutation), it returns null for name
  • Logging in the lambda function reveals that it is correctly fetching the data with graphql()
    • logged result example { id: '0xc3e3', name: 'student' }

This breaks things for me because name is a required field on several of my types. I had to create new payload types without a required ‘name’ just to figure out this was the problem.

The function:

async function testQuery({ args, graphql }) {
    const results = await graphql(`
    query {
      queryRole {
        id
        name
      }
    }
  `, {});
    const role = results?.data?.queryRole?.[0];
    console.log(role);
    return role;
}

Snippets from schema:

enum ROLE_NAMES {
  student
  teacher
  owner
  admin
  other
}

type Role {
  id: ID!
  name: ROLE_NAMES!
}

# RoleReturn is specifically used here so `name` is not required
type RoleReturn {
  id: string
  name: ROLE_NAMES
}

type Query {
  testRoleQuery: Role @lambda
  testRoleQueryWithRoleReturnType: RoleReturn @lambda
}
  • testRoleQuery causes an error - something along the lines of “required field ‘name’ is not present”
  • 'testRoleQueryWithRoleReturnType` returns { id: “some_id”, name: null }

I have reproduced the same results with another type I have, Group. The enum also doesn’t affect it, as Group’s name is of type String.

Can you provide a small schema snippet including the schema types for Role and the schema used to invoke the lambda and the returned type?

1 Like

See my edit to the original post :point_up_2:

1 Like

Have you tested returning any other field with an enum? I think it may be more related to the enum scalar than lambda directly. I would venture to say that the following change would make it work:

enum ROLE_NAMES {
  student
  teacher
  owner
  admin
  other
}

type Role {
  id: ID!
  name: ROLE_NAMES!
}

# RoleReturn is specifically used here so `name` is not required
type RoleReturn @remote {
  id: string
  name: String
}

type Query {
  testRoleQuery: Role @lambda
  testRoleQueryWithRoleReturnType: RoleReturn @lambda
}

if that works with the testRoleQueryWithRoleReturnType query then it is not a problem with a field named ‘name’ but a problem with returning to an enum scalar.

also add @remote if the type is not going to store data locally but only be used for a return type, you probably already knew this though.

1 Like

As I mentioned in my edit:

I have reproduced the same results with another type I have, Group. The enum also doesn’t affect it, as Group’s name is of type String.

It’s 100% not the enum.

And actually, Group has a type field that is an enum that works just fine in the lambda.

Sorry, missed that point. Let me try to spin up a test and verify this behavior. I have seen others using a name field in their lambdas.

1 Like

Hi @jlangree ,Can you please confirm the version of dgraph you are using. We are not able to reproduce this error on slash,20.11 and 21.03 release branch.
Blow i added all the steps that i followed to get lambda and dgraph working

  1. Added below code for lambda function in script.js file
async function testQuery({ args, graphql }) {
    const results = await graphql(`
    query {
      queryRole {
        id
        name
      }
    }
  `, {});
    const role = results.data.queryRole[0];
    console.log(role);
    return role;
}

self.addGraphQLResolvers({
    "Query.testQuery": testQuery
})
  1. Added below Schema
enum ROLE_NAMES {
  student
  teacher
  owner
  admin
  other
}

type Role {
  id: ID!
  name: ROLE_NAMES!
}


type RoleReturn {
  id: String
  name: ROLE_NAMES
}

type Query {
  testQuery: Role @lambda
  testRoleQueryWithRoleReturnType: RoleReturn @lambda
}
  1. Mutatiuon to add Role
mutation{
  addRole(input:{name:student}){
    role{
      name
    }
  }
}
  1. Query Role
    For me, it’s working fine and returning non-null results.
query{
  testQuery {
      id
      name
  }  
}

  1. I am using this command to start lambda server
    docker run -it --rm -p 8686:8686 -v /home/jatin/script.js:/app/script/script.js -e DGRAPH_URL=http://172.17.0.1:8080 dgraph/dgraph-lambda

  2. And then this command to start alpha server assuming you using slash branch
    dgraph alpha --graphql_lambda_url="http://localhost:8686/graphql-worker"

Can you please confirm if you are using some other step to setup lamda server ?
And if so , then share it with us , so that we can reproduce this issue.
Thanks.

I’m doing this in Slash / Dgraph Cloud. So it’s whatever you guys have live right now (I want to say 20.11?).

The logs (which, by the way, are difficult to actually get to work and don’t display the dates unless downloaded) show that the query within the lambda is be successfully executed:

image

Here are my results, using exactly the same schema / lambda code as you have there:

EDIT:
And this is the result for the actual query I want to use. Here, name has type string:

The logs showing the query is being executed properly in the lambda:
image

Hi @jlangree
I just tried the following on slash.
Schema:

enum ROLE_NAMES {
  student
  teacher
  owner
  admin
  other
}

type Role {
  id: ID!
  name: ROLE_NAMES!
}

# RoleReturn is specifically used here so `name` is not required
type RoleReturn {
  id: String
  name: ROLE_NAMES
}

type Query {
  testRoleQuery: Role @lambda
  testRoleQueryWithRoleReturnType: RoleReturn @lambda
}

Mutation:

mutation{
  addRole(input:{name:student}){
    role{
      name
    }
  }
}

Query:

query{
  testRoleQuery {
      id
      name
  }  
}

Response:

{
  "data": {
    "testRoleQuery": {
      "id": "0x2e75e",
      "name": "student"
    }
  }
}

Here is the lambda:

async function testRoleQuery({ args, graphql }) {
    const results = await graphql(`
    query {
      queryRole {
        id
        name
      }
    }
  `, {});
    const role = results?.data?.queryRole?.[0];
    console.log(role);
    return role;
}

self.addGraphQLResolvers({
    "Query.testRoleQuery": testRoleQuery
})

Slash version: v20.11.0-11-gb36b4862

Is there something I am missing?

1 Like

You’re not missing anything. I’ve even tried dropping all data and fully resetting. I’ve tried recreating this with a new type, Stuff. Same issue. I am consistently getting the exact same issue across multiple types - both with queries, and mutations.

UPDATE: After removing everything in the schema except for the testing stuff we’ve got here, it works properly. As soon as I upload the rest of my input schema, the same problems arise again across multiple types.

if possible, can we have full input schema ?

2 Likes

I am finally able to reproduce this issue on 20.11 branch. This bug is already fixed but not available in 20.11 and will be available in 21.03 release coming this month.
I still need to investigate why it works with some part of your schema that we are using earlier.
We had similar kind of bug previously also Custom field resolvers are not always called, Custom Query not working with Float and Integer types

We made many changes related to JSON encoding in master branch which fix such type of bugs.
These changes will be part of 21.03 release and currently available only in master branch only.
PR:perf(GraphQL): Generate GraphQL query response by optimized JSON encoding (GraphQL-730) by abhimanyusinghgaur · Pull Request #7371 · dgraph-io/dgraph · GitHub

1 Like