Skip to content

Split code across different files #276

Open
@artecoop

Description

@artecoop

Hello Everyone,
I have a pretty large project that I'm trying to move to graphql using fastify, mercurius, mercurius-codegen and mercurius-integration-testing

I've split my business logic into modules, so the code is structured like this

src/
├─ modules/
│  ├─ foo/
│  │  ├─ schema.ts
│  │  ├─ resolvers.ts
│  ├─ bar/
│  │  ├─ schema.ts
│  │  ├─ resolvers.ts
...
├─ base.ts
├─ application.ts
├─ server.ts

base.ts contains the root query and mutation, in order to let other schema.ts files to extend

import { gql } from 'mercurius-codegen';

export default gql`
    type Query
    type Mutation
`;

A schema file contains something like this

import { gql } from 'mercurius-codegen';

export default gql`
    extend type Query {
        list: [String!]! 
    }

    extend type Mutation {
        manage(input: String!)
        delete(id: String!)
    }
`;

Here's a resolver:

import { IResolvers } from 'mercurius';

const resolvers: IResolvers = {
    Query: {
        list: async () => await getAll()
    },
    Mutation: {
        manage: async (_root, { input }) => await manage(input),
        delete: async (_root, { id }) => await deleteString(id)
    }
};

export default resolvers;

In order to avoid bloating the server.ts file, I've created an application.ts to import all the schemas and resolvers

import foo from './modules/foo/schema';
import bar from './modules/bar/schema';

export const typeDefs = [foo, bar] ;

import fooResolver from './modules/foo/resolvers';
import barResolver from './modules/bar/resolvers';

export const resolvers = { ...fooResolvers, ...barResolvers };

The problem arises when I need to set up mercurius:

import { resolvers, typeDefs } from './application';

export const app = fastify();

app.register(mercurius, {
    path: '/',
    schema: typeDefs,
    resolvers: resolvers,
    graphiql: process.env.NODE_ENV !== 'production' && 'graphiql'
});

With resolvers merged with the spread operator, all are overwritten by the last one.

Using mergeResolvers from graphql-tools create a different problem

import { mergeResolvers } from '@graphql-tools/merge';

export const resolvers = mergeResolvers([
    fooResolvers,
    barResolvers
]);

give me this error

Argument of type 'IResolvers<any, MercuriusContext>[]' is not assignable to parameter of type 'IResolvers<any, MercuriusContext, Record<string, any>, any> | Maybe<IResolvers<any, MercuriusContext, Record<string, any>, any>>[] | null | undefined'.
  Type 'IResolvers<any, MercuriusContext>[]' is not assignable to type 'Maybe<IResolvers<any, MercuriusContext, Record<string, any>, any>>[]'.
    Type 'IResolvers<any, MercuriusContext>' is not assignable to type 'Maybe<IResolvers<any, MercuriusContext, Record<string, any>, any>>'.
      'string' index signatures are incompatible.
        Type 'GraphQLScalarType<unknown, unknown> | IEnumResolver | (() => any) | IResolverObject<any, MercuriusContext, any> | IResolverOptions<...> | undefined' is not assignable to type 'IUnionTypeResolver | IScalarTypeResolver | IEnumTypeResolver | IInputObjectTypeResolver | ISchemaLevelResolver<...> | IObjectTypeResolver<...> | IInterfaceTypeResolver<...>'.
          Type 'undefined' is not assignable to type 'IUnionTypeResolver | IScalarTypeResolver | IEnumTypeResolver | IInputObjectTypeResolver | ISchemaLevelResolver<...> | IObjectTypeResolver<...> | IInterfaceTypeResolver<...>'.ts(2345)

Any help?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions