apollographql / apollographql/federation
Federation throws Unused Externals error when using nested keys (EXTERNAL_UNUSED)
- Dominant language
- TypeScript
- Stars
- 725
- Forks
- 276
- Avg merge
- 1h 47m
- Merged PRs (30d)
- 1
Description
Using @apollo/federation @0.13.2 and earlier, I've noticed odd behavior when using nested keys.
According to how I'm reading the specs, this should work:
```
const serviceA = {
typeDefs: gql`
type Product @key(fields: "id { nestedA { nestedB } }") {
sku: String!
upc: String!
id: NestedA
}
type NestedA {
nestedA: NestedB
}
type NestedB {
nestedB: String
}
type Query {
some: Product
}
`,
name: 'serviceA',
}
const serviceB = {
typeDefs: gql`
extend type Product @key(fields: "id { nestedA { nestedB } }") {
id: NestedA @external
}
extend type NestedA {
nestedA: NestedB @external
}
extend type NestedB {
nestedB: String @external
}
`,
name: 'serviceB',
}
const serviceList = [serviceA, serviceB]
const { schema: someSchema, errors } = composeAndValidate(serviceList)
console.log('Errors: ', errors)
```
However, I'm getting an EXTERNAL_UNUSED error here:
`"is marked as @external but is not used by a @requires, @key, or @provides directive."`
Looking through the postComposition validator for this, I noticed that the @requires directive does this recursively, while the @key directive doesn't. So I tried it the following way (Note the `noop` with `@requires`):
```
const serviceA = {
typeDefs: gql`
type Product @key(fields: "id { nestedA { nestedB } }") {
sku: String!
upc: String!
id: NestedA
}
type NestedA {
nestedA: NestedB
}
type NestedB {
nestedB: String
}
type Query {
some: Product
}
`,
name: 'serviceA',
}
const serviceB = {
typeDefs: gql`
extend type Product {
id: NestedA @external
noop: String @requires(fields: "id { nestedA { nestedB } }")
}
extend type NestedA {
nestedA: NestedB @external
}
extend type NestedB {
nestedB: String @external
}
`,
name: 'serviceB',
}
const serviceList = [serviceA, serviceB]
const { schema: someSchema, errors } = composeAndValidate(serviceList)
console.log('Errors: ', errors)
```
Which works, but now we have `noop` all over the place.
I'm not all too familiar with the federation code base, but I can take a stab at fixing this, if this isn't intended behavior.
Let me know!
Contributor guide
Research direction
Start with the postComposition validator mentioned in the report and reproduce the issue through composeAndValidate using the provided serviceList schemas. Compare the recursive @requires handling with the @key handling for nested fields, then verify that valid nested keys no longer produce EXTERNAL_UNUSED without requiring a noop field.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend-api-design
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100