Skip to content

Support variables in @requires directives #9583

Description

@jeffutter

Is your feature request related to a problem? Please describe.

There's a little detail on this page; Contribute and Reference Entity Fields, that caught me a bit by surprise:

Starting in Federation v2.1.2, the @\requires directive can include fields that take arguments, like so:
...
The following rules apply:
...

  • Each specified argument value is static; the router always provides the same value.

We have been using the @requires directive to implement a Server-Driven-UI subgraph. The pattern has proven quite useful for creating a nice delineation between our "Data Layer" and our "UI Layer".

In implementing this, we've run into a roadblock. In our specific use-case we have parameterized fields, like icon(size: ImageSize) {...} where our clients pass in some parameters for the image size they need. While we can use the @requires directive to statically request a certain image size, this doesn't allow our clients to pass the desired image size to the field for the UI Component which happens to reference the data-layer icon via @requires (a detail hidden from the consumers of the API).

This particular use-case we can likely work around by accepting the parameters on our UI field, using @requires to access a raw url and formatting it with the size parameters in the SDUI subgraph - this case makes sense to be a UI concern.

There are; however, other upcoming use-cases where this will be a hard blocker. The one that jumps to mind is anything involving pagination. To return a page '3' of some list of widgets we'd have to do something like the following, which would be untenable.

type WidgetListUI {
  widgetData: WidgetList! @external
  widgets(cursor: String, limit: Int): [WidgetItemUI!] @requires(fields: "widgetData(pagination: {cursor: \"\", limit: 100_000}) { widgets { name ....} }")
}

limit: 100_000 ... hopefully you see how this is problematic 😆

Describe the solution you'd like

It would be ideal if we could define arguments on a field that uses @requires and reference those variables inside the @requires

type WidgetListUI {
  widgetData: WidgetList! @external
  widgets(pagination: Pagination!): [WidgetItemUI!] @requires(fields: "widgetData(pagination: $pagination) { widgets { name ....} }")
}

Describe alternatives you've considered

We've considered alternative ways of organizing our schema, we have our hands tied a little due to legacy schema, but also any alternatives provide a less than optimal schema for our consumers.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions