From f6a798a7a60d49e8570f1621824545c4bd36f397 Mon Sep 17 00:00:00 2001 From: Zvonimir Rudinski Date: Sun, 9 Jun 2024 18:20:04 +0200 Subject: [PATCH] add dataloader to graphql modules / yoga template --- .../package-lock.json | 1 + .../package.json | 1 + .../src/gql/graphql.ts | 18 ++++++++++++++---- .../src/modules/example/index.ts | 18 +++++++++++++++++- .../src/modules/example/module-types.ts | 3 ++- .../src/modules/example/resolvers.ts | 6 ++++++ .../modules/example/typedefs/schema.graphql | 5 +++-- 7 files changed, 44 insertions(+), 8 deletions(-) diff --git a/web/other/graphql-modules-yoga-prisma-starter/package-lock.json b/web/other/graphql-modules-yoga-prisma-starter/package-lock.json index 1966cc8..2352be3 100644 --- a/web/other/graphql-modules-yoga-prisma-starter/package-lock.json +++ b/web/other/graphql-modules-yoga-prisma-starter/package-lock.json @@ -12,6 +12,7 @@ "@envelop/graphql-modules": "^6.0.0", "@graphql-tools/load-files": "^7.0.0", "@prisma/client": "^5.15.0", + "dataloader": "^2.2.2", "graphql": "^16.8.1", "graphql-modules": "^2.3.0", "graphql-yoga": "^5.3.1" diff --git a/web/other/graphql-modules-yoga-prisma-starter/package.json b/web/other/graphql-modules-yoga-prisma-starter/package.json index c5cc432..24abd14 100644 --- a/web/other/graphql-modules-yoga-prisma-starter/package.json +++ b/web/other/graphql-modules-yoga-prisma-starter/package.json @@ -21,6 +21,7 @@ "@envelop/graphql-modules": "^6.0.0", "@graphql-tools/load-files": "^7.0.0", "@prisma/client": "^5.15.0", + "dataloader": "^2.2.2", "graphql": "^16.8.1", "graphql-modules": "^2.3.0", "graphql-yoga": "^5.3.1" diff --git a/web/other/graphql-modules-yoga-prisma-starter/src/gql/graphql.ts b/web/other/graphql-modules-yoga-prisma-starter/src/gql/graphql.ts index b58e23b..fc29a50 100644 --- a/web/other/graphql-modules-yoga-prisma-starter/src/gql/graphql.ts +++ b/web/other/graphql-modules-yoga-prisma-starter/src/gql/graphql.ts @@ -7,6 +7,7 @@ export type MakeOptional = Omit & { [SubKey in K]?: export type MakeMaybe = Omit & { [SubKey in K]: Maybe }; export type MakeEmpty = { [_ in K]?: never }; export type Incremental = T | { [P in keyof T]?: P extends ' $fragmentName' | '__typename' ? T[P] : never }; +export type RequireFields = Omit & { [P in K]-?: NonNullable }; /** All built-in and custom scalars, mapped to their actual values */ export type Scalars = { ID: { input: string; output: string; } @@ -29,12 +30,18 @@ export type MutationSetMessageArgs = { export type Query = { __typename?: 'Query'; world: World; + worlds: Array; +}; + + +export type QueryWorldsArgs = { + count: Scalars['Int']['input']; }; export type World = { __typename?: 'World'; - x: Scalars['Int']['output']; - y: Scalars['Int']['output']; + x: Scalars['Float']['output']; + y: Scalars['Float']['output']; }; @@ -109,6 +116,7 @@ export type DirectiveResolverFn; + Float: ResolverTypeWrapper; Int: ResolverTypeWrapper; Mutation: ResolverTypeWrapper<{}>; Query: ResolverTypeWrapper<{}>; @@ -119,6 +127,7 @@ export type ResolversTypes = { /** Mapping between all available schema types and the resolvers parents */ export type ResolversParentTypes = { Boolean: Scalars['Boolean']['output']; + Float: Scalars['Float']['output']; Int: Scalars['Int']['output']; Mutation: {}; Query: {}; @@ -132,11 +141,12 @@ export type MutationResolvers = { world?: Resolver; + worlds?: Resolver, ParentType, ContextType, RequireFields>; }; export type WorldResolvers = { - x?: Resolver; - y?: Resolver; + x?: Resolver; + y?: Resolver; __isTypeOf?: IsTypeOfResolverFn; }; diff --git a/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/index.ts b/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/index.ts index 5523d66..94b53a3 100644 --- a/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/index.ts +++ b/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/index.ts @@ -1,11 +1,27 @@ -import { createModule } from "graphql-modules"; +import { InjectionToken, Scope, createModule } from "graphql-modules"; import { loadFilesSync } from "@graphql-tools/load-files"; import { resolvers } from "./resolvers"; import { join } from "node:path"; +import DataLoader from "dataloader"; +import { ExampleModule } from "./module-types"; + +export const EXAMPLE_DATA_LOADER = new InjectionToken("EXAMPLE_DATA_LOADER"); export const exampleModule = createModule({ id: "example-module", dirname: __dirname, typeDefs: loadFilesSync(join(__dirname, "./typedefs/*.graphql")), + providers: [ + { + provide: EXAMPLE_DATA_LOADER, + scope: Scope.Operation, + useFactory: () => + new DataLoader(async (keys) => { + return keys.map(() => { + return { x: Math.random(), y: Math.random() }; + }); + }), + }, + ], resolvers, }); diff --git a/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/module-types.ts b/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/module-types.ts index 0db3e9b..a236635 100644 --- a/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/module-types.ts +++ b/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/module-types.ts @@ -3,7 +3,7 @@ import * as Types from "../../gql/graphql"; import * as gm from "graphql-modules"; export namespace ExampleModule { interface DefinedFields { - Query: 'world'; + Query: 'world' | 'worlds'; Mutation: 'setMessage'; World: 'x' | 'y'; }; @@ -29,6 +29,7 @@ export namespace ExampleModule { Query?: { '*'?: gm.Middleware[]; world?: gm.Middleware[]; + worlds?: gm.Middleware[]; }; Mutation?: { '*'?: gm.Middleware[]; diff --git a/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/resolvers.ts b/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/resolvers.ts index 5ebb72e..cd4c854 100644 --- a/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/resolvers.ts +++ b/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/resolvers.ts @@ -1,3 +1,4 @@ +import { EXAMPLE_DATA_LOADER } from "."; import { ExampleModule } from "./module-types"; export const resolvers: ExampleModule.Resolvers = { @@ -5,6 +6,11 @@ export const resolvers: ExampleModule.Resolvers = { world: async () => { return { x: 1, y: 2 }; }, + worlds: async (_, { count }, ctx) => { + const keys = Array.from({ length: count }, (_, i) => i.toString()); + + return ctx.injector.get(EXAMPLE_DATA_LOADER).loadMany(keys); + }, }, Mutation: { setMessage: async (_, { message }) => { diff --git a/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/typedefs/schema.graphql b/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/typedefs/schema.graphql index 213f0c9..c8984f8 100644 --- a/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/typedefs/schema.graphql +++ b/web/other/graphql-modules-yoga-prisma-starter/src/modules/example/typedefs/schema.graphql @@ -1,5 +1,6 @@ type Query { world: World! + worlds(count: Int!): [World!]! } type Mutation { @@ -7,6 +8,6 @@ type Mutation { } type World { - x: Int! - y: Int! + x: Float! + y: Float! }