apollographql / apollographql/federation
Union merge input types and enums instead of intersecting
- Dominant language
- TypeScript
- Stars
- 725
- Forks
- 276
- Avg merge
- 1h 47m
- Merged PRs (30d)
- 1
Description
I am trying to adopt Federation 2 but ran into what I think is a huge problem; merging input types and enums.
As it says in the [docs](https://www.apollographql.com/docs/federation/federated-types/composition/#input-types-and-field-arguments), input types and field arguments use the intersection strategy rather than the union strategy because :
> Composition always uses the intersection strategy to merge input types and field arguments. This ensures that the router never passes an argument to a subgraph that doesn't define that argument.
I am having trouble understanding *why* though? Isn't it the router's job to make sure the arguments route to the correct subgraph in the first place? The same way it does for type compositions?
Consider two subgraphs Product and Inventory as per the docs :

From these models, intuitively it makes sense to me for each of the subgraphs to declare their own corresponding inputs :
Product subgraph
```
input ProductCreateInput {
id: Int!
name: String!
price: Int!
}
```
Inventory subgraph
```
input ProductCreateInput {
id: Int!
inStock: Boolean!
}
```
The expectation would be that the input type is merged using the union strategy; the supergraph SDL keeping track of which input fields belong to which subgraph, and the gateway splitting the input argument fields that belong to each subgraph before routing the input data, therefore ensuring the router never passes an argument to a subgraph that doesn't define that argument.
By doing a intersecting merge for input types and enums I feel like there is a huge disconnect between how types are declared and composed vs how input / enums are declared and composed. Input types especially almost directly correspond to the object type, it doesn't really make sense to me why Input types are merged using the intersection strategy. This works when you're building resolvers for querying with keyFields, but for much more complicated queries dealing with collections where the input arguments could aggregate, filter, and sort, coding and querying the arguments get really complicated. It also forces me to declare multiple different input type names like this :
```
input ProductCreateInput_Product {
name: String!
price: Int!
}
```
Inventory subgraph
```
input ProductCreateInput_Inventory {
inStock: Boolean!
}
```
and query them two separate times. For example, if I wanted to create a product with a specific name and also add the inStock field, I would have to query ProductCreateInput_Product then query ProductCreateInput_Inventory. This is just a basic example but I could extend input types to far more complicated arguments like :
Product subgraph
```
input ProductWhereInput {
AND: [ProductWhereInput!]
OR: [ProductWhereInput!]
NOT: [ProductWhereInput!]
id: IntFilter
name: StringFilter
price: IntFilter
}
export interface IntFilter {
equals?: number;
in?: number[];
notIn?: number[];
lt?: number;
lte?: number;
gt?: number;
gte?: number;
not?: NestedIntFilter;
}
export interface StringFilter {
equals?: string;
in?: string[];
notIn?: string[];
contains?: string;
startsWith?: string;
endsWith?: string;
}
```
Inventory subgraph
```
input ProductWhereInput {
AND: [ProductWhereInput!]
OR: [ProductWhereInput!]
NOT: [ProductWhereInput!]
id: IntFilter
inStock: Boolean!
}
export interface IntFilter {
equals?: number;
in?: number[];
notIn?: number[];
lt?: number;
lte?: number;
gt?: number;
gte?: number;
not?: NestedIntFilter;
}
```
in which case it gets more and more difficult to deal with input types.
Do I just have a fundamental misunderstanding of how to implement subgraphs? Are there limitations that has made input types / enum compositions using the union strategy unviable?
Contributor guide
Research direction
Start with the linked Federation documentation on input types and field arguments, then locate the repository's composition implementation and tests for input types and enums. Determine whether union composition can preserve subgraph ownership while routing arguments, and document or implement a decided behavior; the issue names no specific files or tests.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100