-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Description
Problem
Relay currently only knows how to handle these three types of root fields:
- Root field with no arguments and queries a single node.
- e.g.
empirequeries{id: "123", ...}
- e.g.
- Root field with one argument and queries a single node.
- e.g.
ship(id: "456")queries{id: "456", ...}
- e.g.
- Root field with one array argument and queries an array of nodes.
- e.g.
ships(ids: ["456", "789"])queries[{id: "456", ...}, {id: "789", ...}]
- e.g.
However, it has become clear that Relay needs to support any kind of root field. For example:
- Root field with multiple arguments.
- Root field with no arguments and queries an array of nodes.
- Root field that is a connection.
Workaround
For now, the unsupported use cases can be implemented by creating a "global node", commonly called the viewer. You can then add arbitrary fields to viewer.
static fragments = {
viewer: () => Relay.QL`
fragment on Viewer {
# Can return an array of users.
users
}
`
};
Rationale
Historically, GraphQL (as used internally at Facebook) did not have a root type or root fields. Instead, it had special "root calls" such as node, nodes, me, and usernames. Much of Relay was built on top of this assumption that the "root calls" return nodes.
For example, when we fetch me and get {id: "123", ...}, we record the association between the me root field and the node with ID of 123. Now, if we ever encounter another query for me, we can check our store for the node with ID of 123 and resolve the query without having to potentially re-fetch all of the fields we already have for me.
Another example, when we fetch nodes(ids: ["123", "456"]), we record the association between each argument and their respective response nodes. This allows us to fulfill queries for node(id: "123") and node(id: "456") even though we may never have independently queried for either before. (We would also be able to fulfill me if the association from above was established.)
Next Steps
- Support literal enum and input object values (babel plugin: support input object literals #894)
- Support arbitrary values in root calls (Non string identifying argument values #895)
- Define a consistent method for annotating a root argument as "identifying". Identifying arguments have a 1:1 correspondence between the argument value and the
idof the response. Currently all root arguments are assumed to be identifying. - Allow arbitrary root calls with or without identifying arguments.