What is the meaning of viewer field in GraphQL?
Purpose of viewer
root query field
viewer
is not something GraphQL or Relay-specific. Most web applications serve some purposes of its users or viewers. The top level entity to model the various data served to the user can be named as viewer
. You can also name it user
. For example, the Relay todo example has a viewer
root query field:
viewer: {
type: GraphQLUser,
resolve: () => getViewer(),
},
We may also do without viewer
. For instance, Relay starwars example does not have any viewer
root query field.
In short, having this viewer
as a root query field of the GraphQL schema enables us to provide data based on the current user.
Implementation: How to use authentication token together with viewer
My answer follows what is already described in your mentioned article. The steps are:
On the server-side, create a mutation to obtain an authentication token. Let's name it
LoginMutation
. Input to this mutation are the user credentials and the output is an authentication token.On the client-side, if you use relay framework, implement a client-side mutation. After the mutation is successful, store the authentication token.
On the client-side Relay code, add
authToken
parameter for yourviewer
queries. The value ofauthToken
is the authentication token received after successful login mutation.
An alternative
As already mentioned in the article, an alternative way of authenticating user is to do it outside of GraphQL. You may want to see two excellent answers this and this for details.
Jonas Helfer wrote a two-part article on this, which you'll find very useful: Part 1, Part 2
The idea behind the viewer
field (design pattern) was to group the top-level query fields that are only relevant to the currently logged in user. For example:
# EXAMPLE 1
quer {
viewer {
stories { ... } # the list of published stores as well as drafts (current user)
}
stories { ... } # the list of published stories (all users)
}
This currently logged user data was either merged into viewer
field itself or nested under it:
# EXAMPLE 2
query {
viewer {
id
email
displayName
stories { ... }
}
}
# EXAMPLE 3
query {
viewer {
me { id email displayName }
stories { ... }
}
}
All three examples above can be simplified by removing the viewer
field altogether and still have the exact same functionality (recommended):
query {
# The currently logged in user or NULL if not logged in
me {
id
email
displayName
}
# Published stories only (all users)
stories {
...
}
# Published stories as well as drafts (the current user)
stories(drafts: true) {
...
}
}
You can find the complete example in GraphQL API and Relay Starter Kit which can be used either as a reference project or a seed/template for new developments. See api/graphql.ts
.