April 27, 2020
This post is part of a series about Apollo Federation architectural patterns. Check out the introduction for some background on how the example code is structured.
By design, GraphQL does not provide a way to simply fetch all fields for a type without listing them out explicitly. However, you may want to show “everything” for a type-for instance, in a table in an administration interface.
In this example, we can request all data about a User by fetching the attributes
field. The “attributes” service uses @requires directives to compute an array
of label / value objects that we could easily render in a table. Cute,
right?
In actuality, we’re just moving the responsibility of explicitly listing the necessary fields to the server. It also forces us to “stringify” each field, losing valuable type information. But this technique can make certain end-user client code incredibly simple.
(One gotcha to note: currently, @requires directives cannot specify fields
from type extensions, only from the “owning” service of a type. I’m hopeful
that the query planner will eventually gain the ability to “require” data
from anywhere the graph!)
Notice how all of the fields requested from the accounts service are passed as input to the attributes service.
QueryPlan {Sequence {Fetch(service: "/sandbox/src/services/accounts.js") {{user(id: "42") {__typenameidfirstNamelastNameemailAddressaddress {street1street2citystatezip}statusnotificationsEnabled}}},Flatten(path: "user") {Fetch(service: "/sandbox/src/services/attributes.js") {{... on User {__typenameidfirstNamelastNameemailAddressaddress {street1street2citystatezip}statusnotificationsEnabled}} =>{... on User {attributes {labelvalue}}}},},},}
Written by Lenny Burdette in San Francisco. You can follow him on twitter but he doesn't tweet. Opinions written here do not necessarily reflect those of his employers and are subject to change.