Determining What A Resolver UDF Function Returns

This was my original question (moved from Slack as requested):
I have a function:

mutation CreateNewRanking {
  createNewRanking(
    active: true
    rankingname: "Test 6"
    rankingdesc: "t6"
    rankingowneraddr: "0x267be913fc79bbecb3c3ec88332a537d1c593a6i"
  )
}

that successfully adds a new document to the db. However, in Playground I get the following error message:

{
  "data": null,
  "errors": [
    {
      "message": "Can't convert '{ref: ref(id = \"274973443428975110\", class = ref(id = \"Ranking\", class = ref(id = \"classes\"))), ts: 1598493960820000, data: {active: true, rankingname: \"Test 6\", rankingdesc: \"t6\", rankingowneraddr: \"0x267be913fc79bbecb3c3ec88332a537d1c593a6i\"}}' to String",
      "path": [
        "createNewRanking"
      ],
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ]
    }
  ]
}

How do I fix this? thanks …
The answer was:
You are expecting String! but your resolver UDF function is returning a json object with fields ref, ts, data{…}
Follow on question:
I am expecting String! because I originally followed the tutorial here:


Presumably I need then to change the resolver UDF function’s configuration so that it returns
String!

(?) … if so, how do I do that? thanks …

Hi @FreeRoss,
how the UDF

createNewRanking

looks like?

Luigi

Hi Luigi. Thanks for your response:

{
  name: "create_new_ranking",
  role: Role("create_new_ranking"),
  body: Query(
    Lambda(
      ["active", "rankingname", "rankingdesc", "rankingowneraddr"],
      Let(
        {
          doc: Create(Collection("Ranking"), {
            data: {
              active: Var("active"),
              rankingname: Var("rankingname"),
              rankingdesc: Var("rankingdesc"),
              rankingowneraddr: Var("rankingowneraddr")
            }
          })
        },
        Var("doc")
      )
    )
  )
}

Hi @FreeRoss,

looking at your GraphQL schema file, I found that:

createNewRanking(active: Boolean!, rankingname : String!, rankingdesc : String, rankingowneraddr : String!): String! @resolver(name: "create_new_ranking")

In that case you call the mutation createNewRanking using the resolver create_new_ranking passing all arguments and return a string.
The function you wrote, instead, return something like this:

{ ref: Ref(Collection("Ranking"), "275454764103238150"),
  ts: 1598952983930000,
  data:
   { active: true,
     rankingname: 'Test 12',
     rankingdesc: 't12',
     rankingowneraddr: '0x267dsfddgfghbecb3cdfgfdgfhfgfghfga537dddggdvsd' } }

which is exactly what you define in your schema file as a type:

type Ranking
  {
    active : Boolean!
    rankingname : String! @unique
    rankingdesc : String
    rankingowneraddr : String! @unique
    }

To make it working, you should modify your mutation like this:

createNewRanking(active: Boolean!, rankingname : String!, rankingdesc : String, rankingowneraddr : String!): Ranking! @resolver(name: "create_new_ranking")

In this case, the GraphQL engine expects back a Ranking type that can be returned using such mutation

mutation CreateNewRanking {
  createNewRanking(
    active: true
    rankingname: "Test 13"
    rankingdesc: "t13"
    rankingowneraddr: "0x267dsfdfdgsdfdfdgdfgdgdfg88332a537dddggdvsd"
  ) {
    _id
    active
    rankingname
    rankingdesc
    rankingowneraddr
  }
}

Hope this answers your question.
In case you have any doubt, please let me know.

Luigi

1 Like

I recently answered a stackoverflow question that is very similar: https://stackoverflow.com/questions/63654493/filter-by-time-in-graphql-using-faunadb-service

And it’s quite natural that you are confused about the data property. The thing to understand why in one query it’s there and in the other it is not is the following:

  • that data property is typical for a return value that is a page in FaunaDB, both in FaunaDB GraphQL pages (every regular result from generated resolvers is paginated by default) as in FQL pages (when using Pagination())
  • when you write a regular query, FaunaDB interprets the schema and augments it.

This augmentation will actually augment the return types of your regular mutations/queries to Pages. For example, in that stackoverflow post, two queries with the return type [Todo!]! will result in the final schema (which you can see in the GraphQL dashboard):
image
As you can guess, the bottom one had a @resolver tag.

This is where this data property is coming from in the regular queries. Resolver return types do not get transformed. And in your UDF you used paginate so you are returning pages which does have the data property yet your return type does not require one. Selecting a property (such as data) can be done with Select as Luigi explained which essentially removes that property from the result.

1 Like

Thanks Luigi … that fixed it …

Thanks @databrecht. I wasn’t expecting such a detailed response to my rather vague question. I’m coming from a relatively simple Json back end implementation background. My db experience is patchy at best (some SQL many years back). I was drawn across to Fauna by Dirk Johnson’s helpful tutorial linking to Elm .
I’m not surprised there’s quite a bit to learn even for simple queries and mutations. I am reassured by the level of support I have received in relation to my questions, which is motivating me to keep going …

1 Like