Skip to content

Default handling of nested relations #1

@ersinakinci

Description

@ersinakinci

EDIT: I misread the code, so most of this is non-applicable! See my comment below.


I was looking at the following code:

const defaultEmbedQuery = (fieldName, isList) =>
q.Let(
{
ref: q.Select(["data", `${fieldName}Ref`], q.Var("_item_"), null),
},
q.If(q.IsNull(q.Var("ref")), null, q.Get(q.Var("ref")))
)

It seems like unless a type provides an fql property, defaultEmbedQuery is invoked during AST traversal when a node is neither a leaf nor the root, which ends up producing an FQL query that fetches data based on the ${fieldName}Ref property of the top-level field. So in a query like:

query {
  batches {
    items { id }
  }
}

The FQL that gets produced by default for just items looks like:

q.Let(
  { ref: q.Select(["data", "itemsRef"], q.Var("_item_"), null) },
  q.If(q.IsNull(q.Var("ref")), null, q.Get(q.Var("ref")))
)

(Where _item_ refers to the top-level item passed into astToFaunaQuery.) Could you please confirm:

  1. The only way (by default, without defining .fql on the type) to resolve a nested node is by adding a field called ${fieldName}Ref to the data at the top level collection. I.e., in this case, every batch would need an itemsRef.
  2. It’s implied that currently, you can only go one level deep with this kind of nesting. E.g., if you wanted to run the following query:
query {
  batches {
    items {
      titles { id }
    }
  }
}

You would need an itemsRef and titlesRef, _ both_ present on each batch. titlesRef on an item does nothing. Correct?

I think that it would be very helpful to have the default behavior check for a relational ${fieldName}Ref field on the immediate parent of the node being visited. So in the above example, itemsRef should be on each batch and titlesRef should be on each item. Supporting this behavior would mean mapping GraphQL AST paths to the data fetched for each node in the graph, then using the path of the parent node to look up that data and fine the corresponding ${fieldName}Ref. The current behavior, as I understand it, simply stores the top-level node's data as _item_ and looks up all relational attributes against _item_.

Using a path mapping would also eliminate the potential for naming conflicts. For example, query { batches { items { items { ... } } } } would currently use batch.itemsRef to refer to both levels of items.

Also, because I'm new to Fauna: is ${fieldName}Ref the canonical way in Fauna of defining relational attributes? I think that, whichever way it's done normally, there should be an option to override the default relational attribute name without resorting to .fql.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions