Skip to content

feat(event-handler): add support for AppSync GraphQL batch resolvers #4218

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 60 commits into from
Jul 31, 2025

Conversation

arnabrahman
Copy link
Contributor

Summary

This PR will add the ability to register batch resolvers for AppSync GraphQL API.

Changes

  • batchResolver method is introduced to register handler for batch events

    import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
    
    const app = new AppSyncGraphQLResolver();
    
    app.batchResolver<{id: number}>(async (events) => {
      // Process all events in batch
      return events.map(event => ({ id: event.arguments.id, data: 'processed' }));
    }, {
      fieldName: 'getPosts'
    });
    
    export const handler = async (event, context) =>
      app.resolve(event, context);
  • Process events individually

    If you want to process each event individually instead of receiving all events at once, you can set the
    aggregate option to false. In this case, the handler will be called once for each event in the batch,
    similar to regular resolvers.

    import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
    
    const app = new AppSyncGraphQLResolver();
    
    app.batchResolver(async (args, { event, context }) => {
      // Process individual request
      return { id: args.id, data: 'processed' };
    }, {
      fieldName: 'getPost',
      aggregate: false
    });
    
    export const handler = async (event, context) =>
      app.resolve(event, context);
  • Strict error handling

    If you want stricter error handling when processing events individually, you can set the raiseOnError option
    to true. In this case, if any event throws an error, the entire batch processing will stop and the error
    will be propagated. Note that raiseOnError can only be used when aggregate is set to false.

    import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
    
    const app = new AppSyncGraphQLResolver();
    
    app.batchResolver(async (args, { event, context }) => {
      // Process individual request
      return { id: args.id, data: 'processed' };
    }, {
      fieldName: 'getPost',
      aggregate: false,
      raiseOnError: true
    });
    
    export const handler = async (event, context) =>
      app.resolve(event, context);

    You can also specify the type of the arguments using generic type parameters for non-aggregated handlers:

    import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
    
    const app = new AppSyncGraphQLResolver()
    
    app.batchResolver<{ postId: string }>(async (args, { event, context }) => {
      // args is typed as { postId: string }
      return { id: args.postId };
    }, {
      fieldName: 'getPost',
      aggregate: false
    });
    
    export const handler = async (event, context) =>
      app.resolve(event, context);

    As a decorator:

    import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
    
    const app = new AppSyncGraphQLResolver();
    
    class Lambda {
      @app.batchResolver({ fieldName: 'getPosts' })
      async handleGetPosts(events) {
        // Process batch of events
        return events.map(event => ({ id: event.arguments.id, data: 'processed' }));
      }
    
      @app.batchResolver({ fieldName: 'getPost', aggregate: false })
      async handleGetPost(args, { event, context }) {
        // Process individual request
        return { id: args.id, data: 'processed' };
      }
    
      @app.batchResolver({ fieldName: 'getPost', aggregate: false, raiseOnError: true })
      async handleGetPostStrict(args, { event, context }) {
        // Process individual request with strict error handling
        return { id: args.id, data: 'processed' };
      }
    
      async handler(event, context) {
        return app.resolve(event, context, {
          scope: this, // bind decorated methods to the class instance
        });
      }
    }
    
    const lambda = new Lambda();
    export const handler = lambda.handler.bind(lambda);
  • Also, onBatchQuery & onBatchMutation methods are defined for registering batch Query & Mutation events. aggregate & raiseOnError options are also available for these two methods.

    import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
    
    
    const app = new AppSyncGraphQLResolver();
    
    app.onBatchQuery<{ id: number }>('getPosts', async (events) => {
    // Process all events in batch
    return events.map(event => ({ id: event.arguments.id, data: 'processed' }));
    });
    
    export const handler = async (event, context) =>
    app.resolve(event, context);
      import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql';
      
      const app = new AppSyncGraphQLResolver();
      
      app.onBatchMutation<{ id: number }>('createPosts', async (events) => {
        // Process all events in batch
        return events.map(event => ({ id: event.arguments.id, status: 'created' }));
      });
      
      export const handler = async (event, context) =>
        app.resolve(event, context);

Issue number: #4100


By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.

Disclaimer: We value your time and bandwidth. As such, any pull requests created on non-triaged issues might not be successful.

@boring-cyborg boring-cyborg bot added the tests PRs that add or change tests label Jul 27, 2025
@arnabrahman arnabrahman marked this pull request as ready for review July 27, 2025 15:33
@dreamorosi dreamorosi requested review from svozza and sdangol July 27, 2025 16:37
@arnabrahman arnabrahman requested a review from svozza July 29, 2025 04:29
@dreamorosi
Copy link
Contributor

@svozza / @sdangol can you please take a look and leave a review? I believe most of the comments were addressed but unsure.

@svozza
Copy link
Contributor

svozza commented Jul 31, 2025

There's one outstanding issue that we'd like your input on: #4218 (comment).

@dreamorosi
Copy link
Contributor

There's one outstanding issue that we'd like your input on: #4218 (comment).

Thank you, and sorry - I missed that one.

Copy link

@dreamorosi dreamorosi self-requested a review July 31, 2025 11:53
@svozza svozza merged commit 12ac2e4 into aws-powertools:main Jul 31, 2025
46 checks passed
@svozza
Copy link
Contributor

svozza commented Jul 31, 2025

Thank you so @arnabrahman for all your hard work on this!

@arnabrahman arnabrahman deleted the 4100-appsync-graphql-batch branch July 31, 2025 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
event-handler This item relates to the Event Handler Utility size/XXL PRs with 1K+ LOC, largely documentation related tests PRs that add or change tests
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants