Relay: [Modern] Conditionally fetch fields with required input

Created on 26 Apr 2017  路  2Comments  路  Source: facebook/relay

Consider a query like this:

query rootQuery ($userId: String, $loggedIn: Boolean!) {
  viewer {
    user(userId: $userId) @include(if: $loggedIn) {
      id
    }
  }
}

I would like to fetch this query passing in either {userId: null, loggedIn: false} (representing a logged out user) or {userId: <id>, loggedIn true} (representing a logged in user). This query is invalid GraphQL because userId is a required string on the user field. relay-compiler will fail to compile it (Variable "$userId" of type "String" used in position expecting type "String!").

We were able to do this in Relay Classic because Relay would remove fields that were excluded at runtime. I don't see a way to do it in Relay Modern without making $userId required for the query and passing a dummy value, or modifying the schema. Both of those seem hacky. How do you recommend approaching this?

Most helpful comment

Great question. For context, Relay Modern is enforcing standard GraphQL validation rules - this query wouldn't (shouldn't?) be valid in graphiql either, for example. This is because the query's validity depends on the variable values at runtime.

A good workaround is probably to use an empty string, or to specify a default value for the variable, e.g. $userId: String! = "".

All 2 comments

Great question. For context, Relay Modern is enforcing standard GraphQL validation rules - this query wouldn't (shouldn't?) be valid in graphiql either, for example. This is because the query's validity depends on the variable values at runtime.

A good workaround is probably to use an empty string, or to specify a default value for the variable, e.g. $userId: String! = "".

Thanks! I didn't realize you can provide default values like that. I'll go with that solution.

Was this page helpful?
0 / 5 - 0 ratings