nestjs / graphql

GraphQL (TypeScript) module for Nest framework (node.js) 🍷
https://docs.nestjs.com/graphql/quick-start
MIT License
1.45k stars 394 forks source link

Support for Apollo Federation 2 #2141

Closed stringbeans closed 2 years ago

stringbeans commented 2 years ago

Is there an existing issue that is already proposing this?

Is your feature request related to a problem? Please describe it

Currently, it's unclear how to get Apollo Federation 2 to work with NestJS, both code-first and schema-first. I see two main points that need to be addressed:

  1. adding the new extend schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key", "@shareable"]) statement at the top of the typedefs
  2. using the buildSubgraphSchema function from @apollo/subgraph to create the schema

(as referenced here: https://www.apollographql.com/docs/federation/subgraphs)

Describe the solution you'd like

Perhaps a new driver (or replace the existing federation driver) to support the latest versions of:

"@apollo/gateway": "2.0.1",
"@apollo/subgraph": "2.0.1",

Internally, the driver would call buildSubgraphSchema function from @apollo/subgraph to create the schema as suggested in the official apollo federation documentation

Teachability, documentation, adoption, migration strategy

The documentation can reference apollo's official federation docs to understand the differences between Federation 1 and Federation 2.

Federation 2 is also a drop-in solution which is backwards compatible with Federation 1. Usage of new features in Federation 2 are opt-in and will require some minor adjustments to the typedefs

What is the motivation / use case for changing the behavior?

Apollo Federation 2 simplifies the defining of subgraphs as well as how it handles merging and collisions. More here: https://www.apollographql.com/docs/federation/federation-2/new-in-federation-2

stringbeans commented 2 years ago

@kamilmysliwiec i think there are two separate issues. that's why i had opened up the other issue here (https://github.com/nestjs/nest/issues/9472)

this current issue is about supporting Apollo Federation 2

the linked issue (https://github.com/nestjs/nest/issues/9472) is about supporting Federation 1 with the current dependencies

just wanted to mention that. by supporting federation 2 we kill two birds with one stone. but we could also treat it separately :+1:

stringbeans commented 2 years ago

(regarding the support of Apollo Federation 2)

if there was a way to fetch the resolvers map, then i could do something like so...

GraphQLModule.forRoot<ApolloDriverConfig>({
      driver: ApolloDriver,
      autoSchemaFile: true,
      transformAutoSchemaFile: true,
      transformSchema: (schema) => {
        const extendSchema = gql`
        extend schema @link(url: "https://specs.apollo.dev/federation/v2.0",
              import: ["@key", "@shareable"])

        ${printSubgraphSchema(schema)}
        `
        const newSchema = buildSubgraphSchema({
          typeDefs: extendSchema,
          resolvers: /*somehow get the resolvers?*/
        })
        return newSchema
      },
    }),

might work?

kamilmysliwiec commented 2 years ago

Would you like to create a PR for this issue?

hwillson commented 2 years ago

👋 all - we (Apollo) would love to help with this. @stringbeans if you're putting together a PR, definitely let us know if you have any questions. Or if you would prefer to have us look into putting together a PR, let us know that as well. Thanks!

stringbeans commented 2 years ago

@kamilmysliwiec ill try my best! my understanding of the nestjs internals around how the schema is autogenerated from the decorators and resolvers is low, so i will need some time to study it..

@hwillson thanks for the support! my understanding of the apollo side is fairly good, the challenge is just the integration with nestjs. would love some help if you're offering! :heart:

stringbeans commented 2 years ago

@hwillson just coming back to this. i havent had time to explore this further unfortunately. if you and your team would be willing to put together a PR that would be amazing :heart:

mpiantella commented 2 years ago

Is there any tracking on this? Are there plans to support Federation 2?

jsalva commented 2 years ago

+1 @hwillson -- would love to see first class support for apollo federation 2

script-sorcerer commented 2 years ago

+1

sgadzhalov commented 2 years ago

+1

kdawgwilk commented 2 years ago

I am using the schema first approach with the new @apollo/gateway@2.0.3 and @apollo/subgraph@2.0.3 and was able to add

schema @link(url: "https://specs.apollo.dev/federation/v2.0", import: ["@key", "@shareable"]) {
  query: Query
  mutation: Mutation
}

and the schema seems to compose successfully and run just fine. Still need to do more testing with managed federation in a deployed environment but at least with IntrospectAndCompose its all working like I would expect

kdawgwilk commented 2 years ago

Also @nestjs/graphql is using buildSubgraphSchema already so I don't see any changes that need to happen there https://github.com/nestjs/graphql/blob/260ec9e7aebd79c4c63b8eab2f541d1516b41615/packages/graphql/lib/federation/graphql-federation.factory.ts#L75

scorpio-13 commented 2 years ago

Hey Guys ... is there any progress on this at all ... as @kdawgwilk mentioned the schema first might be working (haven't tried though as we have a code first approach on a large scale project and changing this to schema approach is not an option) but i don't think the code first approach is working as expected ... specially when you have a orphanedTypes in a managed federation.

kamilmysliwiec commented 2 years ago

Schema first works out of the box.

Code first may require some tiny tweaks, PRs are more than welcome!

gac3k commented 2 years ago

@stringbeans are you working on that at the moment (for the code first approach adjustments)?

gitn00b1337 commented 2 years ago

We're getting:

The "@apollo/subgraph" package is missing. Please, make sure to install this library ($ npm install @apollo/subgraph) to take advantage of ApolloFederation.

We do use schema-first though. Would someone be able to share the package versions required?

gitn00b1337 commented 2 years ago

For a subgraph not the gateway project:

dependencies": {
    "@apollo/federation": "0.33.1",
    "@apollo/subgraph": "2.0.3",
    "@grpc/grpc-js": "^1.5.3",
    "@grpc/proto-loader": "^0.6.9",
    "@nestjs/apollo": "10.0.14",
    "@nestjs/axios": "latest",
    "@nestjs/common": "^8.0.0",
    "@nestjs/config": "^1.1.6",
    "@nestjs/core": "^8.0.0",
    "@nestjs/graphql": "10.0.14",
    "@nestjs/microservices": "^8.2.6",
    "@nestjs/platform-express": "^8.0.0",
    "@nestjs/platform-fastify": "^8.2.6",
    "@nestjs/terminus": "8.0.3",
    "@nestjs/typeorm": "^8.0.3",
    "@types/dinero.js": "^1.9.0",
    "apollo-server-fastify": "^3.6.2",
    "dinero.js": "^1.9.1",
    "geolib": "^3.3.3",
    "graphql": "15.8.0",
    "moment": "^2.29.1",
    "pg": "^8.7.1",
    "qnos-services-shared": "0.0.55",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.2.0",
    "typeorm": "0.2.41"
  },
  "devDependencies": {
    "@nestjs/cli": "^8.0.0",
    "@nestjs/schematics": "^8.0.0",
    "@nestjs/testing": "^8.0.0",
    "@types/express": "^4.17.13",
    "@types/graphql": "14.5.0",
    "@types/jest": "27.0.2",
    "@types/node": "^16.0.0",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "^27.2.5",
    "nodemon": "^2.0.15",
    "prettier": "^2.3.2",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "^27.0.3",
    "ts-loader": "^9.2.3",
    "ts-morph": "^13.0.3",
    "ts-node": "^10.0.0",
    "ts-proto": "^1.104.0",
    "tsconfig-paths": "^3.10.1",
    "typescript": "^4.3.5"
  },

.

Can't get over this issue without removing @apollo/subgraph. However if we do that, we then get:

GraphQLSchemaValidationError: Unknown directive "@link". Unknown argument "resolvable" on directive "@key".

kdawgwilk commented 2 years ago

@gitn00b1337 you dont need the "@apollo/federation": "0.33.1", package anymore since the @apollo/subgraph lib replaced that for subgraphs

greguintow commented 2 years ago

Hey guys, I opened a PR to support apollo federation 2:

cc @kamilmysliwiec @stringbeans @hwillson

saikrishna5907 commented 2 years ago

Hi, @kamilmysliwiec, when can I expect this PR https://github.com/nestjs/graphql/pull/2251 to be merged into master, still facing the issue for code first approach, or is there any work around until this released. Thanks!

cristian-moreno-ruiz commented 2 years ago

For a subgraph not the gateway project:

dependencies": {
    "@apollo/federation": "0.33.1",
    "@apollo/subgraph": "2.0.3",
    "@grpc/grpc-js": "^1.5.3",
    "@grpc/proto-loader": "^0.6.9",
    "@nestjs/apollo": "10.0.14",
    "@nestjs/axios": "latest",
    "@nestjs/common": "^8.0.0",
    "@nestjs/config": "^1.1.6",
    "@nestjs/core": "^8.0.0",
    "@nestjs/graphql": "10.0.14",
    "@nestjs/microservices": "^8.2.6",
    "@nestjs/platform-express": "^8.0.0",
    "@nestjs/platform-fastify": "^8.2.6",
    "@nestjs/terminus": "8.0.3",
    "@nestjs/typeorm": "^8.0.3",
    "@types/dinero.js": "^1.9.0",
    "apollo-server-fastify": "^3.6.2",
    "dinero.js": "^1.9.1",
    "geolib": "^3.3.3",
    "graphql": "15.8.0",
    "moment": "^2.29.1",
    "pg": "^8.7.1",
    "qnos-services-shared": "0.0.55",
    "reflect-metadata": "^0.1.13",
    "rimraf": "^3.0.2",
    "rxjs": "^7.2.0",
    "typeorm": "0.2.41"
  },
  "devDependencies": {
    "@nestjs/cli": "^8.0.0",
    "@nestjs/schematics": "^8.0.0",
    "@nestjs/testing": "^8.0.0",
    "@types/express": "^4.17.13",
    "@types/graphql": "14.5.0",
    "@types/jest": "27.0.2",
    "@types/node": "^16.0.0",
    "@types/supertest": "^2.0.11",
    "@typescript-eslint/eslint-plugin": "^5.0.0",
    "@typescript-eslint/parser": "^5.0.0",
    "eslint": "^8.0.1",
    "eslint-config-prettier": "^8.3.0",
    "eslint-plugin-prettier": "^4.0.0",
    "jest": "^27.2.5",
    "nodemon": "^2.0.15",
    "prettier": "^2.3.2",
    "source-map-support": "^0.5.20",
    "supertest": "^6.1.3",
    "ts-jest": "^27.0.3",
    "ts-loader": "^9.2.3",
    "ts-morph": "^13.0.3",
    "ts-node": "^10.0.0",
    "ts-proto": "^1.104.0",
    "tsconfig-paths": "^3.10.1",
    "typescript": "^4.3.5"
  },

.

Can't get over this issue without removing @apollo/subgraph. However if we do that, we then get: GraphQLSchemaValidationError: Unknown directive "@link". Unknown argument "resolvable" on directive "@key".

I am using code first approach, and I have literally copy pasted these deps in a blank project, but I still get The \"@apollo/subgraph\" package is missing. Please, make sure to install this library ($ npm install @apollo/subgraph) to take advantage of ApolloFederation.

Any ideas? Will #2251 help on that?

kamilmysliwiec commented 2 years ago

Fixed in 10.0.19.

Example usage:

image

GraphQLModule.forRoot<ApolloDriverConfig>({
  driver: ApolloFederationDriver,
  autoSchemaFile: {
    federation: 2,
  },
})