Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for Apollo Federation directives #2086

Closed
jsangilve opened this issue Jul 1, 2019 · 12 comments

Comments

@jsangilve
Copy link

commented Jul 1, 2019

Is there any way to generate types for a schema using Apollo Federation directives? @key, @external, etc?

I tried to generate them but it doesn't seem to work:

For example:

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

type UserRole {
  type: UserType!
  user: Driver 
}
Error: Cannot extend type "User" because it is not defined. Did you mean "UserRole"?
    Unknown directive "key".
    Unknown directive "external".
    Unknown type "User". Did you mean "UserRole"?

Environment:

  • OS:
  • @graphql-codegen/...: 1.3.1
  • NodeJS: 10.15
@dotansimha

This comment has been minimized.

Copy link
Owner

commented Jul 3, 2019

Hi @jsangilve !
How do you load your schema? Can you please share you codegen.yml?
I think Apollo Federation is using the directives only during it's build process, and strip it while serving the schema.

You can add a file with all the directives (federation-directives.graphql):

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
directive @extends on OBJECT

Then, load it as part of your schema:

schema: 
  - http://remote-schema/graphql
  - federation-directives.graphql
@jsangilve

This comment has been minimized.

Copy link
Author

commented Jul 5, 2019

Thanks for your reply @dotansimha. Will try asap

@dotansimha

This comment has been minimized.

Copy link
Owner

commented Jul 7, 2019

@jsangilve any update? :)

@jsangilve

This comment has been minimized.

Copy link
Author

commented Jul 8, 2019

Hi @dotansimha!

Sorry for the late reply.

I tried your suggestion and the errors for @key and @external directives are gone, but we still have trouble with the types, plus the _FieldSet param (as declared within the directives).

Error: Cannot extend type "User" because it is not defined. Did you mean "UserRole"?
    Unknown type "User". Did you mean "UserRole"?
    Unknown type "_FieldSet".
    Unknown type "_FieldSet".
    Unknown type "_FieldSet".
# codegen.yml
schema: 
  - resources/api.graphql
  - resources/federation-directives.graphql
overwrite: true
generates:
  src/api/types.ts:
    config:
      contextType: ./getContext#ApiContext
      namingConvention:
        enumValues: change-case#upperCase
    plugins:
      - add: "/* tslint:disable */"
      - time
      - typescript-resolvers
@jsangilve

This comment has been minimized.

Copy link
Author

commented Jul 8, 2019

Just to be clear, this is not the Apollo Gateway but a federated service. The type User will never be defined here, but within a different service's schema.

@dotansimha

This comment has been minimized.

Copy link
Owner

commented Jul 8, 2019

My bad, you need the complete Federation directives spec:

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

(you can find it in https://www.apollographql.com/docs/apollo-server/federation/federation-spec/)

@jsangilve

This comment has been minimized.

Copy link
Author

commented Jul 8, 2019

Thanks for the quick reply. Unknown errors for _Fieldset scalar are gone, but the problem type User persists.

Now that I think a little bit more about it, I guess the code generator would only work over the whole GraphQL schema (after federated services are loaded), i.e., it wouldn't be possible to generate types for a service's schema that extends types of another service' schema?

@dotansimha

This comment has been minimized.

Copy link
Owner

commented Jul 8, 2019

@jsangilve yeah that makes sense. Is it possible to access the other schemas you depend on? (via URL?)
Because if so, you can specify it as well as part of the schema field, and it will load and merge it.

@dotansimha

This comment has been minimized.

Copy link
Owner

commented Aug 12, 2019

Available since 1.5.0. You don't need to specify or add the directives now, just make sure to add federation: true and it will add it and generate a compatible signature.

@dotansimha dotansimha closed this Aug 12, 2019

@jsangilve

This comment has been minimized.

Copy link
Author

commented Aug 12, 2019

@dotansimha thanks for the update!

We've been sorting out other problems with federation and didn't have time to look on this. I'll comment on this issue as soon as I give it a try with 1.5.0

@kamilkisiela

This comment has been minimized.

Copy link
Collaborator

commented Aug 13, 2019

@jsangilve We would love to collaborate with you on Federation in GraphQL Code Generator! Also happy to hear suggestions 🚀 If you're interested we could talk on our Slack.

@jsangilve

This comment has been minimized.

Copy link
Author

commented Aug 15, 2019

@kamilkisiela thx for working on the PR. It's quite busy right now, but I'll get back to you as soon I find time to test this. The service that's using the codegen it's not extending types right now :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
3 participants
You can’t perform that action at this time.