Skip to content

Handle Fragment expansion with variables fully #107

Open
@jlouis

Description

@jlouis

Background

Suppose we have a fragment

fragment M on Monster {
  ...
  hitPoints(above: $foo)
  ...
}

Then this fragment is valid as a spread in any query Q which defines

query Q($foo : Int) { ... }

But not in a query

query Q($foo: String) { ... }

Also, note that if we have another fragment

fragment R on Room {
    description(language: $foo)
}

Then if language : Locale you are not allowed to mix fragments M and R in the same query.

Other observations

  • This holds transitively. If M refers to a subfragment I on Iventory and that fragment refers to $bar, then M also refers to $bar.
  • These tests must happen in the type checking phase.

Implementation

The reason this has been held off for a while is that it isn't that simple to implement:

  • Introduce the notion of a type signature for fragment. This allows us to ask if a fragment "fits" when it is called by a fragment spread.
  • Inline spreads can just produce their signature and we can then check it afterwards.
  • A fragment is implemented as a function from its signature to its expansion. Thus, the function signature is verified by checking if we can "call" the fragment from the spread with a valid type.
  • When handling fragments, they can refer to other fragments. When this happens, we must run fragception and DFS the fragment world. We track already handled fragments in order to detect if we have a cycle in the fragment expansion. This runs in linear time over the fragments and is going to be reasonably fast. Also, it moves the cycle validation into the type checker where it belongs.
  • Value coercion still happens at the execution phase for variables. So this will still work as expected.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions