Need a way to access a UDF via GraphQL and get custom data returned

Guys,

I have the following FQL.

Map(
     Paginate(Distinct(Match(Index("clordersku_by_clorder"), "PzdJhnWOYD"))),
     purveyorId =>
     Paginate(Match(Index("clordersku_by_purveyor"), "PzdJhnWOYD", purveyorId))
)

It returns data like this

{
  data: [
    {
      data: [
        ["18470", "fife-0114", "Off to Bed with a Good Book Card", "1"],
        ["18470", "fife-0114", "Off to Bed with a Good Book Card", "jjj"]
      ]
    },
    {
      data: [
        ["18476", "BRWI-0101", "Sourdough Loaf ", "1"],
        ["18476", "BRWI-0101", "Sourdough Loaf ", "jjj"],
        ["18476", "BRWI-0106", "White Bloomer (Sliced) ", "1"],
        ["18476", "BRWI-0106", "White Bloomer (Sliced) ", "jjj"],
        ["18476", "BRWI-0108", "Tomato Bloomer Loaf", "1"],
        ["18476", "BRWI-0108", "Tomato Bloomer Loaf", "jjj"]
      ]
    }
  ]
}

So this bit I managed to do on my own. But i need this working for the graphql endpoint because ive a 3rd party integration. So i thought of creating a function like

Query(
  Lambda(
    ["orderId"],
    Map(
      Paginate(Distinct(Match(Index("clordersku_by_clorder"), "PzdJhnWOYD"))),
      Lambda(
        "purveyorId",
        Paginate(
          Match(Index("clordersku_by_purveyor"), [
            "PzdJhnWOYD",
            Var("purveyorId")
          ])
        )
      )
    )
  )
)

using the same FQL i did before. but how do i now call this UDF via graphql and retrieve the data?

Did you take a look on the docs here https://docs.fauna.com/fauna/current/api/graphql/functions ?

Yes. i have created a UDF and mapped to graphql query with a resolver and returning an embedded object as output. Now the results come out as null. Here’s my schema in order to match the output i mentioned above:

type Query {
   clorderSkusByPurveyor(orderId: String!): clorderSkusPayload! @resolver(name: "getSkusByPurveyor", paginated: false)
}

type CLOrderSKUsOutput @embedded {
  code: String
  name: String
  pieces_per_pack: String
  reference: String
}

type clorderSkusPayload @embedded {
  data: [SkuPurveyor]
}

type SkuPurveyor @embedded {
  data: [CLOrderSKUsOutput]
}

why i have created clorderSkusPayload SkuPurveyor and CLOrderSKUsOutput types are because of the output i wanted to match. The output i got directly using the FQL is

{
  data: [
    {
      data: [
        ["18470", "fife-0114", "Off to Bed with a Good Book Card", "1"],
        ["18470", "fife-0114", "Off to Bed with a Good Book Card", "jjj"]
      ]
    },
    {
      data: [
        ["18476", "BRWI-0101", "Sourdough Loaf ", "1"],
        ["18476", "BRWI-0101", "Sourdough Loaf ", "jjj"],
        ["18476", "BRWI-0106", "White Bloomer (Sliced) ", "1"],
        ["18476", "BRWI-0106", "White Bloomer (Sliced) ", "jjj"],
        ["18476", "BRWI-0108", "Tomato Bloomer Loaf", "1"],
        ["18476", "BRWI-0108", "Tomato Bloomer Loaf", "jjj"]
      ]
    }
  ]
}

but using graphql query i get

{
  "data": {
    "clorderSkusByPurveyor": {
      "data": [
        {
          "data": [
            {
              "reference": null,
              "code": null,
              "name": null,
              "pieces_per_pack": null
            },
            {
              "reference": null,
              "code": null,
              "name": null,
              "pieces_per_pack": null
            }
          ]
        },
        {
          "data": [
            {
              "reference": null,
              "code": null,
              "name": null,
              "pieces_per_pack": null
            },
            {
              "reference": null,
              "code": null,
              "name": null,
              "pieces_per_pack": null
            },
            {
              "reference": null,
              "code": null,
              "name": null,
              "pieces_per_pack": null
            },
            {
              "reference": null,
              "code": null,
              "name": null,
              "pieces_per_pack": null
            },
            {
              "reference": null,
              "code": null,
              "name": null,
              "pieces_per_pack": null
            },
            {
              "reference": null,
              "code": null,
              "name": null,
              "pieces_per_pack": null
            }
          ]
        }
      ]
    }
  }
}

Any idea why i get null?

The GraphQL schema doesn’t seem to match the structure coming back in the FQL query. The nested data property in your FQL response is an array of strings. I think the data will need to look like this to match your GraphQL Schema:

{
  data: [
    {
      data: [
        {
          code: "18470",
          reference: "fife-0114",
          name: "Off to Bed with a Good Book Card",
          pieces_per_pack: "1"
         }
      ]
    },

Yes thats the problem. Im not sure how to get ab object within the array instead of the array of strings. I need to modify the FQL in such a way right? Any idea?

What does the data look like if you pull it up in the Fauna UI Collections screen?

Also can you post the FQL or GraphQL mutation you are using to insert the data?

The set of mutations are quite different. so the mutation i have used is the default mutation which writes to couple of collections. The data looks like the one i posted above when i run the following:

Map(
 Paginate(Distinct(Match(Index("clordersku_by_clorder"), "PzdJhnWOYD"))),
   purveyorId =>
   Paginate(Match(Index("clordersku_by_purveyor"), "PzdJhnWOYD", purveyorId))
)

here’s the clordersku_by_purveyor index:

CreateIndex({
  name: "clordersku_by_purveyor",
    source: Collection("clorderskus"),
    terms: [{ field: ["data", "order", "data", "id"] },{ field: ["data", "reference"] }],
    values: [{ field: ["data","reference"] },{ field: ["data","code"] },{ field: ["data","name"]             },{ field: ["data","pieces_per_pack"] } ]
  })

Is there any way i can make the object how we want like this - https://stackoverflow.com/questions/61104940/how-to-get-nested-documents-in-faunadb

Hi @pavan168

The top level ‘data’ is the result of the first Paginate operation. But your GraphQL schema specifies pagination:false. This can be simplified.

First try

clorderSkusByPurveyor(orderId: String!): 
    [SkuPurveyor]! @resolver(name: "getSkusByPurveyor", paginated: false)

And in your query, if you don’t want it paginated, you should Select the list out.

Select(['data'],
  Map(
     Paginate(Distinct(Match(Index("clordersku_by_clorder"), "PzdJhnWOYD"))),
     purveyorId =>
     Paginate(Match(Index("clordersku_by_purveyor"), "PzdJhnWOYD", purveyorId))
  )
)

That might be enough.

Otherwise it looks like your on the right path!

In general:

You can return an object or array from the query.

Here is a gist with a Template for building deeply nested FQL queries

We resolved this issued by updating the UDF to return the Json object with field and values instead of just the values.

Update(
  Function("getSkusByPurveyor"),
  {
body: Query(Lambda(["orderId"], 
Map(Paginate(Distinct(Match(Index("clordersku_by_clorder"), "PzdJhnWOYD"))), 
Lambda("purveyorId", Map(Paginate(Match(Index("clordersku_by_purveyor"), ["PzdJhnWOYD", Var("purveyorId")])), 
Lambda(
  "value",
  {
   "reference": Select([0],Var("value")),
   "code": Select([1],Var("value")),
   "name": Select([2],Var("value")),
   "pieces_per_pack": Select([3],Var("value"))
 }))))))})

@pavan168 Please increase the paginate size otherwise you will not see all documents.

:man_facepalming: that part is also clear to me now that it is a new day and not past bed time!

Very glad this is working for you, @pavan168.

Awesome support by @Jay-Fauna and @ptpaterson. Thank you once again.