From 1637b35d9ceecac96b1133d34d81bad0d3411258 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niccol=C3=B2=20Belli?= Date: Mon, 25 Sep 2023 19:39:36 +0200 Subject: [PATCH] feat: port microservice example to yoga --- examples/accounts-microservice/package.json | 7 ++- .../src/accounts-microservice.ts | 33 +++++------ .../accounts-microservice/src/app-server.ts | 57 +++++++++---------- modules/module-core/src/index.ts | 42 ++++++++------ yarn.lock | 5 +- 5 files changed, 71 insertions(+), 73 deletions(-) diff --git a/examples/accounts-microservice/package.json b/examples/accounts-microservice/package.json index 5c84d5acc..709145ba7 100644 --- a/examples/accounts-microservice/package.json +++ b/examples/accounts-microservice/package.json @@ -5,7 +5,7 @@ "main": "lib/index.js", "license": "MIT", "scripts": { - "start": "NODE_ENV=development yarn run -T nodemon -w src -x ts-node src/accounts-microservice.ts & sleep 2 && yarn run -T nodemon -w src -x ts-node src/app-server.ts", + "start": "NODE_ENV=development yarn run -T nodemon -w src -x ts-node src/accounts-microservice.ts & sleep 15 && yarn run -T nodemon -w src -x ts-node src/app-server.ts", "start-services": "docker-compose up -d", "prestart": "yarn run start-services", "build": "yarn run -T tsc", @@ -18,8 +18,8 @@ "@accounts/mongo": "^0.34.0", "@accounts/password": "^0.32.1", "@accounts/server": "^0.33.1", - "@apollo/server": "4.9.3", - "@apollo/server-plugin-landing-page-graphql-playground": "4.0.1", + "@envelop/core": "4.0.1", + "@envelop/graphql-modules": "5.0.1", "@graphql-tools/delegate": "10.0.3", "@graphql-tools/merge": "9.0.0", "@graphql-tools/schema": "10.0.0", @@ -28,6 +28,7 @@ "@graphql-tools/wrap": "10.0.1", "graphql": "16.8.1", "graphql-modules": "2.2.0", + "graphql-yoga": "4.0.4", "lodash": "4.17.21", "node-fetch": "2.7.0", "tslib": "2.6.2" diff --git a/examples/accounts-microservice/src/accounts-microservice.ts b/examples/accounts-microservice/src/accounts-microservice.ts index e9e9091d1..3bc158538 100644 --- a/examples/accounts-microservice/src/accounts-microservice.ts +++ b/examples/accounts-microservice/src/accounts-microservice.ts @@ -5,10 +5,9 @@ import { createAccountsMongoModule } from '@accounts/module-mongo'; import { createApplication, createModule, gql } from 'graphql-modules'; import { AuthenticationServicesToken } from '@accounts/server'; import { AccountsPassword } from '@accounts/password'; -import { ApolloServer } from '@apollo/server'; -import { startStandaloneServer } from '@apollo/server/standalone'; -import { ApolloServerPluginLandingPageDisabled } from '@apollo/server/plugin/disabled'; -import { ApolloServerPluginLandingPageGraphQLPlayground } from '@apollo/server-plugin-landing-page-graphql-playground'; +import { createServer } from 'node:http'; +import { createYoga } from 'graphql-yoga'; +import { useGraphQLModules } from '@envelop/graphql-modules'; (async () => { const typeDefs = gql` @@ -24,7 +23,7 @@ import { ApolloServerPluginLandingPageGraphQLPlayground } from '@apollo/server-p } `; - const { createOperationController, createSchemaForApollo } = createApplication({ + const app = createApplication({ modules: [ createAccountsCoreModule({ tokenSecret: 'secret' }), createAccountsPasswordModule({ @@ -55,25 +54,19 @@ import { ApolloServerPluginLandingPageGraphQLPlayground } from '@apollo/server-p global: true, }, ], - schemaBuilder: buildSchema({ typeDefs }), + schemaBuilder: buildSchema(), }); - const schema = createSchemaForApollo(); + const { createOperationController } = app; - // Create the Apollo Server that takes a schema and configures internal stuff - const server = new ApolloServer({ - schema, - plugins: [ - process.env.NODE_ENV === 'production' - ? ApolloServerPluginLandingPageDisabled() - : ApolloServerPluginLandingPageGraphQLPlayground(), - ], - }); - - const { url } = await startStandaloneServer(server, { - listen: { port: 4003 }, + const yoga = createYoga({ + plugins: [useGraphQLModules(app)], context: (ctx) => context(ctx, { createOperationController }), }); - console.log(`🚀 Server ready at ${url}`); + const server = createServer(yoga); + + server.listen(4003, () => { + console.info('Server is running on http://localhost:4003/graphql'); + }); })(); diff --git a/examples/accounts-microservice/src/app-server.ts b/examples/accounts-microservice/src/app-server.ts index 2de99bf0b..8ecb72ed4 100644 --- a/examples/accounts-microservice/src/app-server.ts +++ b/examples/accounts-microservice/src/app-server.ts @@ -11,27 +11,26 @@ import { context, createAccountsCoreModule, } from '@accounts/module-core'; -import { createAccountsPasswordModule } from '@accounts/module-password'; import { delegateToSchema } from '@graphql-tools/delegate'; import { createApplication, createModule, gql } from 'graphql-modules'; import { AuthenticationServicesToken } from '@accounts/server'; -import { AccountsPassword } from '@accounts/password'; -import { ApolloServer } from '@apollo/server'; -import { startStandaloneServer } from '@apollo/server/standalone'; -import { ApolloServerPluginLandingPageDisabled } from '@apollo/server/plugin/disabled'; -import { ApolloServerPluginLandingPageGraphQLPlayground } from '@apollo/server-plugin-landing-page-graphql-playground'; +import { createServer } from 'node:http'; +import { createYoga } from 'graphql-yoga'; +import { useGraphQLModules } from '@envelop/graphql-modules'; -const accountsServerUri = 'http://localhost:4003/'; +const accountsServerUri = 'http://localhost:4003/graphql'; (async () => { - const typeDefs = gql` + const myTypeDefs = gql` type PrivateType @auth { field: String } extend type Query { - # Example of how to get the userId from the context and return the current logged in user or null + # Example of how to delegate to another field of the remote schema. Returns the currently logged in user or null. me: User + # Returns the currently logged in userId directly from the context without querying the remote schema. + myId: ID publicField: String # You can only query this if you are logged in privateField: String @auth @@ -45,7 +44,7 @@ const accountsServerUri = 'http://localhost:4003/'; } `; - const resolvers = { + const myResolvers = { Query: { me: { resolve: (parent, args, context, info) => { @@ -59,6 +58,7 @@ const accountsServerUri = 'http://localhost:4003/'; }); }, }, + myId: (parent, args, context) => context.userId, publicField: () => 'public', privateField: () => 'private', privateFieldWithAuthResolver: authenticated(() => { @@ -74,8 +74,6 @@ const accountsServerUri = 'http://localhost:4003/'; }, }; - // // Note: the following steps are optional and only required if you want to stitch the remote accounts schema with your apps schema. - const remoteExecutor: AsyncExecutor = async ({ document, variables, context }) => { console.log('context: ', context); const query = print(document); @@ -99,7 +97,7 @@ const accountsServerUri = 'http://localhost:4003/'; const { authDirectiveTypeDefs, authDirectiveTransformer } = authDirective('auth'); - const { createOperationController, createSchemaForApollo } = createApplication({ + const app = createApplication({ modules: [ createAccountsCoreModule({ tokenSecret: 'secret', @@ -107,17 +105,20 @@ const accountsServerUri = 'http://localhost:4003/'; // verify access tokens without any additional session logic micro: true, }), - createAccountsPasswordModule(), - createModule({ id: 'app', typeDefs }), + createModule({ + id: 'app', + typeDefs: myTypeDefs, + resolvers: myResolvers, + }), ], providers: [ { provide: AuthenticationServicesToken, - useValue: { password: AccountsPassword }, + useValue: {}, global: true, }, ], - schemaBuilder: () => + schemaBuilder: ({ typeDefs, resolvers }) => authDirectiveTransformer( stitchSchemas({ subschemas: [remoteSubschema], @@ -127,22 +128,16 @@ const accountsServerUri = 'http://localhost:4003/'; ), }); - const schema = createSchemaForApollo(); + const { createOperationController } = app; - // Create the Apollo Server that takes a schema and configures internal stuff - const server = new ApolloServer({ - schema, - plugins: [ - process.env.NODE_ENV === 'production' - ? ApolloServerPluginLandingPageDisabled() - : ApolloServerPluginLandingPageGraphQLPlayground(), - ], - }); - - const { url } = await startStandaloneServer(server, { - listen: { port: 4000 }, + const yoga = createYoga({ + plugins: [useGraphQLModules(app)], context: (ctx) => context(ctx, { createOperationController }), }); - console.log(`🚀 Server ready at ${url}`); + const server = createServer(yoga); + + server.listen(4000, () => { + console.info('Server is running on http://localhost:4000/graphql'); + }); })(); diff --git a/modules/module-core/src/index.ts b/modules/module-core/src/index.ts index 1a8317b75..ead9babef 100644 --- a/modules/module-core/src/index.ts +++ b/modules/module-core/src/index.ts @@ -1,4 +1,4 @@ -import { createModule, Provider } from 'graphql-modules'; +import { createModule, gql, Provider } from 'graphql-modules'; import { mergeTypeDefs } from '@graphql-tools/merge'; import { User, IContext } from '@accounts/types'; import { @@ -33,22 +33,30 @@ export type AccountsContextGraphQLModules = IContext< export const createAccountsCoreModule = (config: AccountsCoreModuleConfig) => createModule({ id: 'accounts-core', - typeDefs: mergeTypeDefs( - [ - makeSchema(config), - TypesTypeDefs, - getQueryTypeDefs(config), - getMutationTypeDefs(config), - ...getSchemaDef(config), - ], - { - useSchemaDefinition: config.withSchemaDefinition, - } - ), - resolvers: { - [config.rootQueryName || 'Query']: Query, - [config.rootMutationName || 'Mutation']: Mutation, - }, + typeDefs: config.micro + ? gql` + extend type Query { + _accounts_core: String + } + ` + : mergeTypeDefs( + [ + makeSchema(config), + TypesTypeDefs, + getQueryTypeDefs(config), + getMutationTypeDefs(config), + ...getSchemaDef(config), + ], + { + useSchemaDefinition: config.withSchemaDefinition, + } + ), + ...(!config.micro && { + resolvers: { + [config.rootQueryName || 'Query']: Query, + [config.rootMutationName || 'Mutation']: Mutation, + }, + }), providers: () => { const providers: Provider[] = [ { diff --git a/yarn.lock b/yarn.lock index 23c07503d..65d600c77 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4080,8 +4080,8 @@ __metadata: "@accounts/mongo": "npm:^0.34.0" "@accounts/password": "npm:^0.32.1" "@accounts/server": "npm:^0.33.1" - "@apollo/server": "npm:4.9.3" - "@apollo/server-plugin-landing-page-graphql-playground": "npm:4.0.1" + "@envelop/core": "npm:4.0.1" + "@envelop/graphql-modules": "npm:5.0.1" "@graphql-tools/delegate": "npm:10.0.3" "@graphql-tools/merge": "npm:9.0.0" "@graphql-tools/schema": "npm:10.0.0" @@ -4091,6 +4091,7 @@ __metadata: "@types/lodash": "npm:4.14.199" graphql: "npm:16.8.1" graphql-modules: "npm:2.2.0" + graphql-yoga: "npm:4.0.4" lodash: "npm:4.17.21" node-fetch: "npm:2.7.0" tslib: "npm:2.6.2"