dangcuuson / graphql-schema-typescript

Generate TypeScript from GraphQL's schema type definitions
191 stars 36 forks source link

Apollo Federation Support #48

Closed itsJess1ca closed 4 years ago

itsJess1ca commented 4 years ago

This tool looks incredibly helpful, however I'm running into a blocker thats stopping me being able to use unfortunately.

My Schema is distributed using Apollo's Managed Federation, which essentially means the schema may or may not have some types explicitly defined. For example I may have a schema like:

extend type User @key(fields: "id") {
  id: ID! @external
}
type Product {
  id: ID!
  name: String!
  created_by: User!
}

In this case, User is stubbed out and resolved by a different service, and when attempting to generate types, I get the following

Error: Unknown type "User".

Cannot extend type "Mutation" because it is not defined.

Cannot extend type "Query" because it is not defined.

Cannot extend type "User" because it is not defined.

I think a resolution to this would be to essentially not require a "base" definition of a type (User in this case). Though of course this would affect non-federated schema's, so making it a config option would be needed.

The other issue that arises is the directives used (key & external in this example), as these aren't defined either by each service.

Apollo's schema for directives is the following:

scalar _Any
scalar _FieldSet

# a union of all types that use the @key directive
union _Entity

type _Service {
  sdl: String
}

extend type Query {
  _entities(representations: [_Any!]!): [_Entity]!
  _service: _Service!
}

directive @external on FIELD_DEFINITION
directive @requires(fields: _FieldSet!) on FIELD_DEFINITION
directive @provides(fields: _FieldSet!) on FIELD_DEFINITION
directive @key(fields: _FieldSet!) on OBJECT | INTERFACE

# this is an optional directive discussed below
directive @extends on OBJECT | INTERFACE

Currently I am just prepending this to my schema at the time of generation, but it would be nice if the federation config option prepended this itself perhaps