Skip to content

docs(event-handler): add examples on how to drop messages #3924

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 2 commits into from
May 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions docs/features/event-handler/appsync-events.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,15 +167,24 @@ This is useful when you want to for example:

You can enable this with the `aggregate` parameter:

!!! note "Aggregate Processing"
When enabling `aggregate`, your handler receives a list of all events, requiring you to manage the response format. Ensure your response includes results for each event in the expected [AppSync Request and Response Format](#appsync-request-and-response-format).

=== "Aggregated processing"

```typescript hl_lines="17 32 34"
--8<-- "examples/snippets/event-handler/appsync-events/aggregatedProcessing.ts"
```

When enabling `aggregate`, your handler receives a list of all the events, requiring you to manage the response format. Ensure your response includes results for each event in the expected [AppSync Request and Response Format](#appsync-request-and-response-format).

If you want to omit one or more events from the response, you can do so by excluding them from the returned array. Likewise, if you want to discard the entire batch and prevent subscribers from receiving it, you can return an empty array.

=== "Aggregated processing with partial results"

```typescript hl_lines="17 19"
--8<-- "examples/snippets/event-handler/appsync-events/aggregatedProcessingWithPartialResults.ts"
```

1. You can also return an empty array `[]` to discard the entire batch and prevent subscribers from receiving it.

### Handling errors

You can filter or reject events by throwing exceptions in your resolvers or by formatting the payload according to the expected response structure. This instructs AppSync not to propagate that specific message, so subscribers will not receive it.
Expand Down Expand Up @@ -237,7 +246,7 @@ You can also do content-based authorization for channel by throwing an `Unauthor

=== "UnauthorizedException"

```typescript hl_lines="3 14 20"
```typescript hl_lines="3 14 25-27"
--8<-- "examples/snippets/event-handler/appsync-events/unauthorizedException.ts"
```

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { AppSyncEventsResolver } from '@aws-lambda-powertools/event-handler/appsync-events';
import type { AppSyncEventsPublishEvent } from '@aws-lambda-powertools/event-handler/types';
import type { Context } from 'aws-lambda';

const app = new AppSyncEventsResolver();

app.onPublish(
'/default/foo/*',
async (events) => {
const payloadsToReturn: AppSyncEventsPublishEvent['events'] = [];

for (const event of events) {
if (event.payload.includes('foo')) continue;
payloadsToReturn.push(event);
}

return payloadsToReturn; // (1)!
},
{ aggregate: true }
);

export const handler = async (event: unknown, context: Context) =>
app.resolve(event, context);
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,18 @@ app.onPublish('/*', () => {
throw new UnauthorizedException('You can only publish to /default/foo');
});

app.onSubscribe('/default/foo', () => true);
app.onSubscribe('/private/*', async (info) => {
const userGroups =
info.identity?.groups && Array.isArray(info.identity?.groups)
? info.identity?.groups
: [];
const channelGroup = 'premium-users';

app.onSubscribe('/*', () => {
throw new UnauthorizedException('You can only subscribe to /default/foo');
if (!userGroups.includes(channelGroup)) {
throw new UnauthorizedException(
`Subscription requires ${channelGroup} group membership`
);
}
});

export const handler = async (event: unknown, context: Context) =>
Expand Down
4 changes: 2 additions & 2 deletions packages/event-handler/src/types/appsync-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,12 +168,12 @@ type RouteOptions<T extends boolean | undefined = false> = {
*/
type AppSyncEventsEvent = {
/**
* The `identity` field is marked as `unknown` because it varies based on the authentication type used in AppSync.
* The `identity` field varies based on the authentication type used for the AppSync API.
* When using an API key, it will be `null`. When using IAM, it will contain the AWS credentials of the user. When using Cognito,
* it will contain the Cognito user pool information. When using a Lambda authorizer, it will contain the information returned
* by the authorizer.
*/
identity: unknown;
identity: null | Record<string, unknown>;
result: null;
request: {
headers: Record<string, string>;
Expand Down