UNPKG

@theguild/federation-composition

Version:

Open Source Composition library for Apollo Federation

193 lines (163 loc) • 5.33 kB
# 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`