UDF called directly returns values, but when called as GraphQL resolver returned values are null

Hi there. I’m trying to setup my app’s user registration, but can’t seem to get my createUser GraphQL mutation to return the created user and associated token secret that I plan on sending to the user to verify their email. The user document and associated token appear to be created in the DB, but the mutation returns null values for both. I’m still finding my footing with FQL / GraphQL, so I’m probably missing something silly :upside_down_face:

Below is a simplified version of my GraphQL schema that still reproduces the issue

type Mutation {
	createUser(input: CreateUserInput!): AuthPayload @resolver(name: "create_user")
}

type User {
	username: String! @unique(index: "user_by_username")
	email: String! @unique(index: "user_by_email")
	verified: Boolean!
}

input CreateUserInput {
	username: String!
	email: String!
	password: String!
}

type AuthPayload {
	token: String
	user: User
}

And here is my create_user UDF resolver

Query(
  Lambda(
    ["input"],
    Let(
      {
        user: Create(Collection("User"), {
          credentials: { password: Select("password", Var("input")) },
          ttl: TimeAdd(Now(), 60, "minutes"),
          data: {
            username: Select("username", Var("input")),
            email: Select("email", Var("input")),
            verified: false,
          }
        }),
        verificationToken: Create(Tokens(), {
          instance: Select(["ref"], Var("user")),
          ttl: TimeAdd(Now(), 60, "minutes")
        })
      },
      {
        token: Select("secret", Var("verificationToken")),
        user: Select("data", Var("user"))
      }
    )
  )
)

You can see that when I try to run the mutation through the GraphQL playground, I just get null values back

Though the document was successfully created when I look at the User collection

    {
      "ref": Ref(Collection("User"), "300164913489248776"),
      "ts": 1622518418880000,
      "ttl": Time("2021-06-01T04:33:38.530704Z"),
      "data": {
        "username": "notarealuser",
        "email": "notareal@email.com",
        "verified": false
      }
    }

And if I try running the create_user UDF directly from the shell, it looks like it’s returning valid data? Guessing I’m missing something obvious with how to access those return values via the GraphQL mutation, hmm…

Call("create_user", {"username":"x", "email": "x@fakeemail.com", "password": "12345678"})

{
  token: "fnEEKqfZAeACCgQO9FnlkAYNR9kiLRhE58GMeq6nm6tQnaAZreo",
  user: {
    username: "x",
    email: "x@fakeemail.com",
    verified: false
  }
}

>> Time elapsed: 401ms

AuthPayload should be decorated with @embedded. The schema currently is expecting an entire Fauna Document to be returned, i.e. with a Ref, timestamp, and data.

1 Like

Thank you so much for the reply! I would not have thought to add @embedded to a return type that never actually gets embedded in any of my schema collections, but can see the point you’re making.

Unfortunately though, now I’m getting a new error. "message": "Ref or Set expected, Object provided.", "code": "invalid argument" No user document is created either, unlike before. Confusing why it’s seemingly rejecting the input argument now, when that part didn’t change?

Calling the UDF directly through the UI Shell and bypassing GraphQL still seems to work as expected, though.

Call("create_user", {"username":"x", "email": "x@fakeemail.com", "password": "12345678"})

{
  token: "fnEEKz-cBZACCgQO9FnlkAYNyMF_G2_vYMhNRmU4L7wosGn8ENw",
  user: {
    username: "x",
    email: "x@fakeemail.com",
    verified: false
  }
}

>> Time elapsed: 137ms

That one is coming from returning an object, where the schema calls for a User:

type AuthPayload @embedded {
	token: String
	user: User # <-- Expects a Ref to a user
}

In your UDF, can you try this?

{
  token: Select("secret", Var("verificationToken")),
  //user: Select("data", Var("user"))
  user: Select("ref", Var("user"))
}

The UDF response would be more like:

Call("create_user", {"username":"x", "email": "x@fakeemail.com", "password": "12345678"})

{
  token: "fnEEKz-cBZACCgQO9FnlkAYNyMF_G2_vYMhNRmU4L7wosGn8ENw",
  user: Ref(Collection("User"), "168476826416584187136864163")
}
1 Like

That did the trick!! Wow, thank you for the help, I appreciate it so much. I feel like this really helped a few things click for me that I have been majorly struggling with. Cheers!

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.