@theguild/federation-composition
Version:
Open Source Composition library for Apollo Federation
193 lines (163 loc) ⢠5.33 kB
Markdown
# Federation Composition
Supports all Federation versions prior to v2.4.0. Drop-in replacement for `@apollo/composition`.
š§ Work in progress, so please check [TODOs](#todos).
## Comparison with `@apollo/composition`
- Open Source (MIT License)
- identical API
- same set of validation rules and exact same error messages
- produces Supergraph SDL (can be used with Apollo Router and every tool that supports Supergraph
SDL)
- does not support Hints
- a lot faster! 5x faster when composing and validating simple schemas, but 28x faster at big scale.
## Installation
```bash
# NPM
npm install @theguild/federation-composition
# PNPM
pnpm add @theguild/federation-composition
# Yarn
yarn add @theguild/federation-composition
```
## Usage
```ts
import { parse } from 'graphql'
import { composeServices, compositionHasErrors } from '@theguild/federation-composition'
const result = composeServices([
{
name: 'users',
typeDefs: parse(/* GraphQL */ `
extend schema @link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@key"])
type User @key(fields: "id") {
id: ID!
name: String!
}
type Query {
users: [User]
}
`)
},
{
name: 'comments',
typeDefs: parse(/* GraphQL */ `
extend schema
@link(url: "https://specs.apollo.dev/federation/v2.3", import: ["@key", "@external"])
extend type User @key(fields: "id") {
id: ID! @external
comments: [Comment]
}
type Comment {
id: ID!
text: String!
author: User!
}
`)
}
])
if (compositionHasErrors(result)) {
console.error(result.errors)
} else {
console.log(result.supergraphSdl)
}
```
## Contributing
Install the dependencies:
```bash
pnpm install
```
Run the tests:
```bash
pnpm test
```
### How to help?
- Grab one of the failing tests and fix it.
- Add new tests to cover more cases.
- Add missing rules.
- Look for `// TODO:` comments in the code and fix/implement them.
- Todos with `// TODO: T[NUMBER]` are on Notion.
- Look for `skipIf` or `skip` in the tests.
- Refactor code (piece by piece) if you feel like it.
## Supergraph SDL Composition
ā
Done
## Validation
š§ Work in progress
### Validation rules
- ā
`NO_QUERIES`
- ā
`TYPE_KIND_MISMATCH`
- ā
`EXTENSION_WITH_NO_BASE`
- ā
`FIELD_TYPE_MISMATCH`
- ā
`FIELD_ARGUMENT_TYPE_MISMATCH`
- ā
`EXTERNAL_TYPE_MISMATCH`
- ā
`ENUM_VALUE_MISMATCH`
- ā
`EMPTY_MERGED_ENUM_TYPE`
- ā
`EMPTY_MERGED_INPUT_TYPE`
- ā
`OVERRIDE_SOURCE_HAS_OVERRIDE`
- ā
`EXTERNAL_MISSING_ON_BASE`
- ā
`REQUIRED_ARGUMENT_MISSING_IN_SOME_SUBGRAPH`
- ā
`REQUIRED_INPUT_FIELD_MISSING_IN_SOME_SUBGRAPH`
- ā
`EXTERNAL_ARGUMENT_MISSING`
- ā
`INPUT_FIELD_DEFAULT_MISMATCH`
- ā
`FIELD_ARGUMENT_DEFAULT_MISMATCH`
- ā
`DEFAULT_VALUE_USES_INACCESSIBLE`
- ā
`ONLY_INACCESSIBLE_CHILDREN`
- ā
`REFERENCED_INACCESSIBLE`
- ā
`INTERFACE_KEY_MISSING_IMPLEMENTATION_TYPE`
- ā
`INVALID_FIELD_SHARING`
- ā
`PROVIDES_INVALID_FIELDS_TYPE`
- ā
`INVALID_GRAPHQL`
- ā
`OVERRIDE_ON_INTERFACE`
- ā
`OVERRIDE_FROM_SELF_ERROR`
- ā
`QUERY_ROOT_TYPE_INACCESSIBLE`
- ā
`PROVIDES_UNSUPPORTED_ON_INTERFACE`
- ā
`REQUIRES_UNSUPPORTED_ON_INTERFACE`
- ā
`KEY_UNSUPPORTED_ON_INTERFACE`
- ā
`KEY_INVALID_FIELDS_TYPE`
- ā
`KEY_FIELDS_HAS_ARGS`
- ā
`KEY_FIELDS_SELECT_INVALID_TYPE`
- ā
`KEY_INVALID_FIELDS`
- ā
`REQUIRES_INVALID_FIELDS`
- ā
`REQUIRES_INVALID_FIELDS_TYPE`
- ā
`MERGED_DIRECTIVE_APPLICATION_ON_EXTERNAL`
- ā
`INTERFACE_KEY_NOT_ON_IMPLEMENTATION`
- ā
`PROVIDES_FIELDS_MISSING_EXTERNAL`
- ā
`REQUIRES_FIELDS_MISSING_EXTERNAL`
- ā
`PROVIDES_ON_NON_OBJECT_FIELD`
- ā
`INVALID_SUBGRAPH_NAME`
- ā
`PROVIDES_FIELDS_HAS_ARGS`
- ā
`PROVIDES_INVALID_FIELDS`
- ā
`EXTERNAL_UNUSED`
- ā
`DIRECTIVE_COMPOSITION_ERROR`
- ā
`ROOT_QUERY_USED`
- ā
`ROOT_MUTATION_USED`
- ā
`ROOT_SUBSCRIPTION_USED`
- ā
`INVALID_SHAREABLE_USAGE`
- ā
`DIRECTIVE_DEFINITION_INVALID`
- ā
`KEY_DIRECTIVE_IN_FIELDS_ARG`
- ā
`PROVIDES_DIRECTIVE_IN_FIELDS_ARG`
- ā
`REQUIRES_DIRECTIVE_IN_FIELDS_ARG`
- ā
`TYPE_DEFINITION_INVALID`
- ā
`OVERRIDE_COLLISION_WITH_ANOTHER_DIRECTIVE`
### TODOs
- [ ] `INTERFACE_OBJECT_USAGE_ERROR`
- [ ] `INTERFACE_FIELD_NO_IMPLEM`
- [ ] `SATISFIABILITY_ERROR`
- [ ] `DISALLOWED_INACCESSIBLE`
- [ ] `DOWNSTREAM_SERVICE_ERROR`
- [ ] `EXTERNAL_ARGUMENT_DEFAULT_MISMATCH`
- [ ] `EXTERNAL_ARGUMENT_TYPE_MISMATCH`
- [ ] `EXTERNAL_COLLISION_WITH_ANOTHER_DIRECTIVE`
- [ ] `IMPLEMENTED_BY_INACCESSIBLE`
- [ ] `INVALID_FEDERATION_SUPERGRAPH`
- [ ] `LINK_IMPORT_NAME_MISMATCH`
- [ ] `REQUIRED_INACCESSIBLE`
- [ ] `SHAREABLE_HAS_MISMATCHED_RUNTIME_TYPES`
- [ ] `UNSUPPORTED_FEATURE`
- [ ] `UNSUPPORTED_LINKED_FEATURE`
- [ ] `SATISFIABILITY_ERROR` - deeply nested key fields
- [ ] `SATISFIABILITY_ERROR` - fragments in keys
- [ ] `SATISFIABILITY_ERROR` - support interfaces... (kill me)
- [ ] `SATISFIABILITY_ERROR` - @require - check if fields defined by @require can be resolved by
current subgraph or by moving to other subgraphs.
- [ ] `SATISFIABILITY_ERROR` - @provides?
- [ ] more accurate key fields comparison (I did string ā string but we need to make it better)
- [ ] support `@interfaceObject`
- [ ] support `[String!]!` and `[String!]` comparison, not only `String!` vs `String`