Add custom GraphQL fields

Learn how to add custom GraphQL fields and resolvers to your MJAPI deployment

In this guide, we will walk you through the process of adding custom GraphQL fields and resolvers to your MJAPI deployment using TypeGraphQL decorators provided by @memberjunction/server. By the end of this guide, you'll be able to extend or modify the default behavior of the base resolvers, such as FileResolver, to fit your application's specific needs.

Prerequisites

  • Basic understanding of GraphQL and TypeGraphQL.
  • Familiarity with TypeScript.
  • A working MJAPI deployment.

Adding a New Field

To add a new field to an existing resolver, we'll use TypeGraphQL decorators to define and implement the custom field. In this example, we'll add a DownloadURL field to the FileResolver.

Step-by-Step Guide

  1. Create a Custom Resolver Class: Extend the base FileResolver class to create your custom resolver.
  2. Define the Field Resolver: Use the @FieldResolver decorator to define the new field.

Example Code

Here's a simplified example of how to add a DownloadURL field to the FileResolver:

import { Resolver, FieldResolver, Root, Ctx } from '@memberjunction/server';
import { File_, FileResolver } from '../generated/generated';

@Resolver(File_)
export class CustomFileResolver extends FileResolver {
  @FieldResolver(() => String)
  async DownloadUrl(@Root() file: File_, @Ctx() { userPayload }: AppContext) {
    // Any custom logic goes here
    const url = 'https://memberjunction.com';

    return url;
  }
}

Explanation

  • @Resolver: This decorator marks the class as a GraphQL resolver for the File_ type. Learn more.
  • @FieldResolver: This decorator defines a new field in the GraphQL schema. It specifies the return type and the method to resolve the field. Learn more.

By adding the DownloadURL field resolver, you can extend the GraphQL schema to include additional data that is not part of the original File_ type.

Modifying Existing Fields

To modify the behavior of existing fields, you can override methods from the base resolver class. This allows you to customize the logic for mutations or queries to better suit your application's requirements.

Step-by-Step Guide

  1. Extend the Base Resolver Class: Create a custom resolver class that extends the base FileResolver.
  2. Override Methods: Use the @Mutation decorator to override existing methods and implement custom logic.

Example Code

Here's an example of how to modify the behavior of CreateFile, UpdateFile, and DeleteFile mutations:

import { Resolver, Mutation, Arg, Ctx, PubSub } from '@memberjunction/server';
import { CreateFileInput, UpdateFileInput, File_, FileResolver } from '../generated/generated';

@Resolver(File_)
export class CustomFileResolver extends FileResolver {
  @Mutation(() => CreateFilePayload)
  async CreateFile(
    @Arg('input', () => CreateFileInput) input: CreateFileInput,
    @Ctx() { dataSource, userPayload }: AppContext,
    @PubSub() pubSub: PubSubEngine
  ) {
    // Custom logic for CreateFile
  }

  @Mutation(() => File_)
  async UpdateFile(
    @Arg('input', () => UpdateFileInput) input: UpdateFileInput,
    @Ctx() { dataSource, userPayload }: AppContext,
    @PubSub() pubSub: PubSubEngine
  ) {
    // Custom logic for UpdateFile
  }

  @Mutation(() => File_)
  async DeleteFile(@Arg('ID', () => Int) ID: number, @Ctx() { dataSource, userPayload }: AppContext, @PubSub() pubSub: PubSubEngine) {
    // Custom logic for DeleteFile or just pass through
    return super.DeleteFile(ID, { dataSource, userPayload }, pubSub);
  }
}

Explanation

  • @Mutation: This decorator is used to mark a method as a GraphQL mutation. It allows you to define custom logic for mutations like CreateFile, UpdateFile, and DeleteFile. Learn more.

By overriding these methods, you can change the default behavior of the base resolver and implement custom logic that meets your application's specific requirements.

Additional Resources

For more detailed examples and a real-life implementation of these concepts, refer to the FileResolver on GitHub.

By following these steps, you can effectively add custom GraphQL fields and modify existing resolver behavior in your MJAPI deployment, providing more flexibility and functionality for your application.