apollographql / apollographql/federation

Extending types without @key directive

Open
#714 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
725
Forks
276
Avg merge
1h 47m
Merged PRs (30d)
1

Description

**Package Version** - "@apollo/federation": "0.22.0"

**TL;DR**
Is it possible to extend types that doesn't need keys and federation would know where to send requested fields to in parallel (as with general Query type)?

Given a schemas of 2 services: `products` and `reviews`. When federation merges these 2 schemas, no validation errors returned and schemas are composed successfully. The key type to look at is `ProductsMutation`, defined in **Products** and extended by **Reviews**.

**Schema of `products` service**
```graphql
extend type Query {
products(limit: Int): [Product!]
product(id: ID!): Product
}

extend type Mutation {
products: ProductsMutation
}

# namespaced mutation
type ProductsMutation {
save(data: NewProductData!): SaveProductResult
}

type SaveProductResult {
product: Product
error: Error
}

input NewProductData {
name: String!
}

type Product @key(fields: "id") {
id: ID!
url: String!
name: String!
}
```

**Schema of `reviews` service**
```graphql
extend type Query {
reviews: [Review!]
}

extend type Product @key(fields: "id") {
id: ID! @external
reviews: [Review!]
}

type Review {
id: ID!
text: String!
}

# extending namespaced mutation
extend type ProductsMutation {
addReview(data: NewReviewData!): ReviewAddedResult
}

input NewReviewData {
text: String!
productId: ID!
}

type ReviewAddedResult {
header: String!
text: String!
actionText: String!
}
```

Given two mutations:
```graphql
mutation CreateProduct($data: NewProductData!) {
products {
save(data: $data) {
product {
name
url
id
}
}
}
}

mutation AddReview($review:NewReviewData!) {
products {
addReview(data:$review) {
text
header
actionText
}
}
}
```

`CreateProduct` is sent to **Products** service, as well as `AddReview` mutation. As **Products** service doesn't know about `addReview` mutation it fails with graphql validation error. Is it expected behaviour? If expected, then why validation does not fail? If unexpected, then, I suppose it's a bug.

Query plan of execution these mutations:
**CreateProduct**
```
QueryPlan {
Fetch(service: "products") {
{
products {
save(data: $data) {
product {
name
url
id
}
}
}
}
},
}
```

**AddReview**
```
QueryPlan {
Fetch(service: "products") {
{
products {
addReview(data: $review) {
text
header
actionText
}
}
}
},
}
```

Contributor guide

Open the contributing guide

Research direction

Start with the products and reviews schemas and compare the composed query plans shown for CreateProduct and AddReview. Trace how the extended ProductsMutation field is validated and assigned to a service; done means the behavior is either corrected with coverage for this schema pair or documented as an intentional limitation.

Written by the indexing model from the issue text.

Assessment

Tech stack
graphql, typescript
Domain
api, distributed-systems
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.