Description
According to the spec, "Directives Are Unique Per Location" validation is defined like this:
Directives are used to describe some metadata or behavioral change on the definition they apply to. When more than one directive of the same name is used, the expected metadata or behavior becomes ambiguous, therefore only one of each directive is allowed per location.
In the light of recent GraphQL spec changes (extensions on all types and the schema itself) and other developments in the community, I would like to suggest to reconsider the inclusions of this validation rule or limiting it's scope to a subset of directives.
I would like to show 2 cases where it might be beneficial to allow non-unique directives.
Example 1: adding more information
In this scenario, directives might add more information. The order of directives is insignificant.
Considering the schema delegation case where multiple GraphQL schemas are merged into one. I can define the config like this (with the current limitation):
schema
@includeGraphQL(schemas: [{
name: "schema1"
url: "http://some.server/graphql"
}, {
name: "schema2"
url: "http://another.server/graphql"
}]) {
query: Query
}
If the limitation is lifted, I can potentially split the schema in 2 files like this:
# file 1
schema
@includeGraphQL(
name: "schema1",
url: "http://some.server/graphql") {
query: Query
}
# file 2
extend schema
@includeGraphQL(
name: "schema2",
url: "http://another.server/graphql")
This provides more modularity (and, I would argue, simplicity), even in absence of an extension:
schema
@includeGraphQL(
name: "schema1",
url: "http://some.server/graphql")
@includeGraphQL(
name: "schema2",
url: "http://another.server/graphql") {
query: Query
}
Example 2: chaining directives/data transformation
In this scenario, I would like to transform the data in a chain. A small subset of directives might represent reusable logic for a data retrieval and transformation. In this case the ordering the directives is significant.
For example, if I have a set of directives to retrieve data from an external HTTP service, I can define a field like this:
type Query {
users: [User]
@httpGet(url: "...")
@jsonPath(path: "$.results")
@enrichData
@jsonPath(path: "$.profile")
}
Possible solutions
We can tackle this in a number of ways:
- Remove the validation altogether. In this case, we need to reconsider what to do with ambiguous
@skip
,@include
and potentially other custom directives - Limit the validation to only
@skip
and@include
directives - Limit the validation to only these directives that are explicitly marked as "unique". This implies that we need to introduce a new option in the directive definition.
- Leave "Directives Are Unique Per Location" validation as-is
I would really appreciate your opinions and comments on this suggestion.