-
Notifications
You must be signed in to change notification settings - Fork 171
docs(event-handler): add AppSync GraphQL docs page #4120
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
Changes from 1 commit
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
8ab2772
docs(event-handler): add AppSync GraphQL docs page
dreamorosi 3606fe8
docs: address feedback
dreamorosi 944b514
Apply suggestions from code review
dreamorosi 08ce1e1
chore: remove duplicate import
dreamorosi a1b9276
Merge branch 'docs/appsync_graphql' of github.com:aws-powertools/powe…
dreamorosi File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,179 @@ | ||
--- | ||
title: AppSync GraphQL | ||
description: Event Handler for AppSync GraphQL APIs | ||
status: new | ||
--- | ||
|
||
Event Handler for AWS AppSync GraphQL APIs simplifies routing and processing of events in AWS Lambda functions. It allows you to define resolvers for GraphQL types and fields, making it easier to handle GraphQL requests without the need for complex VTL or JavaScript templates. | ||
|
||
```mermaid | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/diagrams/intro.mermaid" | ||
``` | ||
|
||
## Key Features | ||
|
||
- Route events based on GraphQL type and field keys | ||
- Automatically parse API arguments to function parameters | ||
- Handle GraphQL responses and errors in the expected format | ||
|
||
## Terminology | ||
|
||
**[Direct Lambda Resolver](https://docs.aws.amazon.com/appsync/latest/devguide/direct-lambda-reference.html){target="_blank"}**. A custom AppSync Resolver that bypasses Apache Velocity Template (VTL) and JavaScript templates, and automatically maps your function's response to a GraphQL field. | ||
|
||
**[Batching resolvers](https://docs.aws.amazon.com/appsync/latest/devguide/tutorial-lambda-resolvers.html#advanced-use-case-batching){target="_blank"}**. A technique that allows you to batch multiple GraphQL requests into a single Lambda function invocation, reducing the number of calls and improving performance. | ||
|
||
## Getting started | ||
|
||
???+ tip "Tip: Designing GraphQL Schemas for the first time?" | ||
Visit [AWS AppSync schema documentation](https://docs.aws.amazon.com/appsync/latest/devguide/designing-your-schema.html){target="_blank"} to understand how to define types, nesting, and pagination. | ||
|
||
### Required resources | ||
|
||
You must have an existing AppSync GraphQL API and IAM permissions to invoke your Lambda function. That said, there is no additional permissions to use Event Handler as routing requires no dependency (_standard library_). | ||
|
||
This is the sample infrastructure we are using for the initial examples with a AppSync Direct Lambda Resolver. | ||
|
||
=== "gettingStartedSchema.graphql" | ||
|
||
```typescript | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/templates/gettingStartedSchema.graphql" | ||
``` | ||
|
||
=== "template.yaml" | ||
|
||
```yaml hl_lines="59-60 71-72 94-95 104-105 112-113" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/templates/gettingStartedSam.yaml" | ||
``` | ||
|
||
### Registering a resolver | ||
|
||
You can register functions to match GraphQL types and fields with one of three methods: | ||
|
||
- `onQuery()` - Register a function to handle a GraphQL Query type. | ||
- `onMutation()` - Register a function to handle a GraphQL Mutation type. | ||
- `resolver()` - Register a function to handle a GraphQL type and field. | ||
|
||
!!! question "What is a type and field?" | ||
A type would be a top-level **GraphQL Type** like `Query`, `Mutation`, `Todo`. A **GraphQL Field** would be `listTodos` under `Query`, `createTodo` under `Mutation`, etc. | ||
|
||
The function receives the parsed arguments from the GraphQL request as its first parameter. We will also take care of parsing the response or catching errors and returning them in the expected format. | ||
dreamorosi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
#### Query resolver | ||
|
||
When registering a resolver for a `Query` type, you can use the `onQuery()` method. This method allows you to define a function that will be invoked when a GraphQL Query is made. | ||
|
||
```typescript hl_lines="2 8 10 21" title="Registering a resolver for a Query type" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/gettingStartedOnQuery.ts" | ||
``` | ||
|
||
#### Mutation resolver | ||
|
||
Similarly, you can register a resolver for a `Mutation` type using the `onMutation()` method. This method allows you to define a function that will be invoked when a GraphQL Mutation is made. | ||
|
||
```typescript hl_lines="2-5 11 13 25" title="Registering a resolver for a Mutation type" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/gettingStartedOnMutation.ts" | ||
``` | ||
|
||
#### Generic resolver | ||
|
||
When you want to have more control over the type and field, you can use the `resolver()` method. This method allows you to register a function for a specific GraphQL type and field including custom types. | ||
|
||
```typescript hl_lines="2 8 10 27-30" title="Registering a resolver for a type and field" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/gettingStartedResolver.ts" | ||
``` | ||
|
||
#### Using decorators | ||
|
||
If you prefer to use the decorator syntax, you can instead use the same methods on a class method to register your handlers. Learn more about how Powertools for TypeScript supports [decorators](../../getting-started/usage-patterns.md). | ||
|
||
```typescript hl_lines="3-6 12 15 27 38 60" title="Using decorators to register a resolver" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/gettingStartedDecorators.ts" | ||
``` | ||
|
||
### Scalar functions | ||
|
||
When working with [AWS AppSync Scalar types](https://docs.aws.amazon.com/appsync/latest/devguide/scalars.html){target="_blank"}, you might want to generate the same values for data validation purposes. | ||
|
||
For convenience, the most commonly used values are available as helper functions within the module. | ||
|
||
```typescript hl_lines="2-6" title="Creating key scalar values" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/gettingStartedScalarFunctions.ts" | ||
``` | ||
|
||
Here's a table with their related scalar as a quick reference: | ||
|
||
| Scalar type | Scalar function | Sample value | | ||
| ---------------- | --------------- | -------------------------------------- | | ||
| **ID** | `makeId` | `e916c84d-48b6-484c-bef3-cee3e4d86ebf` | | ||
| **AWSDate** | `awsDate` | `2022-07-08Z` | | ||
| **AWSTime** | `awsTime` | `15:11:00.189Z` | | ||
| **AWSDateTime** | `awsDateTime` | `2022-07-08T15:11:00.189Z` | | ||
| **AWSTimestamp** | `awsTimestamp` | `1657293060` | | ||
|
||
## Advanced | ||
|
||
### Nested mappings | ||
|
||
!!! note | ||
|
||
The following examples use a more advanced schema. These schemas differ from [initial sample infrastructure we used earlier](#required-resources). | ||
dreamorosi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
You can register the same route handler multiple times to resolve fields with the same return value. | ||
|
||
=== "Nested Mappings Example" | ||
|
||
```typescript hl_lines="8 33-39" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/advancedNestedMappings.ts" | ||
``` | ||
|
||
1. If omitted, the `typeName` defaults to `Query`. | ||
|
||
=== "Nested Mappings Schema" | ||
|
||
```graphql hl_lines="6 20" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/templates/advancedNestedMappingsSchema.graphql" | ||
``` | ||
|
||
### Accessing Lambda context and event | ||
|
||
You can access to the original Lambda event or context for additional information. These are passed to the handler function as optional arguments. | ||
dreamorosi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
=== "Access event and context" | ||
|
||
```typescript hl_lines="10" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/advancedAccessEventAndContext.ts" | ||
``` | ||
|
||
1. The `event` parameter contains the original AppSync event and has type `AppSyncResolverEvent` from the `@types/aws-lambda`. | ||
|
||
### Logging | ||
|
||
By default, the utility uses the global `console` logger and emits only warnings and errors. | ||
|
||
You can change this behavior by passing a custom logger instance to the `AppSyncGraphQLResolver` or `Router` and setting the log level for it, or by enabling [Lambda Advanced Logging Controls](https://docs.aws.amazon.com/lambda/latest/dg/monitoring-cloudwatchlogs-advanced.html) and setting the log level to `DEBUG`. | ||
|
||
When debug logging is enabled, the resolver will emit logs that show the underlying handler resolution process. This is useful for understanding how your handlers are being resolved and invoked and can help you troubleshoot issues with your event processing. | ||
|
||
For example, when using the [Powertools for AWS Lambda logger](../logger.md), you can set the `LOG_LEVEL` to `DEBUG` in your environment variables or at the logger level and pass the logger instance to the constructor to enable debug logging. | ||
|
||
=== "Debug logging" | ||
|
||
```typescript hl_lines="11" | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/advancedDebugLogging.ts" | ||
``` | ||
|
||
=== "Logs output" | ||
|
||
```json | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/samples/debugLogExcerpt.json" | ||
``` | ||
|
||
## Testing your code | ||
|
||
You can test your resolvers by passing an event with the shape expected by the AppSync GraphQL API resolver. | ||
|
||
Here's an example of how you can test your resolvers that uses a factory function to create the event shape: | ||
|
||
```typescript | ||
--8<-- "examples/snippets/event-handler/appsync-graphql/advancedTestYourCode.ts" | ||
``` |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
--- | ||
title: Event Handler | ||
description: Simplify routing and processing of events in AWS Lambda functions | ||
--- | ||
|
||
<!-- markdownlint-disable MD043 --> | ||
|
||
<div class="grid cards" markdown> | ||
|
||
- __AppSync Events API__ | ||
|
||
--- | ||
|
||
Event Handler for AWS AppSync real-time events, easily handle publish and subscribe events with dedicated handler methods. | ||
|
||
[:octicons-arrow-right-24: Read more](./appsync-events.md) | ||
|
||
- __AppSync GraphQL API__ | ||
|
||
--- | ||
|
||
Event Handler for AWS AppSync GraphQL APIs, it allows you to define resolvers for GraphQL types and fields, making it easier to handle requests without the need for complex VTL or JavaScript templates. | ||
|
||
[:octicons-arrow-right-24: Read more](./appsync-graphql.md) | ||
|
||
- __Bedrock Agents__ | ||
|
||
--- | ||
|
||
Create [Amazon Bedrock Agents](https://docs.aws.amazon.com/bedrock/latest/userguide/agents.html#agents-how) and focus on building your agent's logic without worrying about parsing and routing requests. | ||
|
||
[:octicons-arrow-right-24: Read more](./bedrock-agents.md) | ||
|
||
</div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
examples/snippets/event-handler/appsync-graphql/advancedAccessEventAndContext.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql'; | ||
import { Logger } from '@aws-lambda-powertools/logger'; | ||
import type { Context } from 'aws-lambda'; | ||
|
||
const logger = new Logger({ | ||
serviceName: 'serverlessAirline', | ||
dreamorosi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}); | ||
const app = new AppSyncGraphQLResolver({ logger }); | ||
|
||
app.onQuery<{ id: string }>('getTodo', async ({ id }, { event, context }) => { | ||
const { headers } = event.request; // (1)! | ||
const { awsRequestId } = context; | ||
logger.info('headers', { headers, awsRequestId }); | ||
|
||
return { | ||
id, | ||
title: 'Todo Title', | ||
completed: false, | ||
}; | ||
}); | ||
|
||
export const handler = async (event: unknown, context: Context) => | ||
app.resolve(event, context); |
29 changes: 29 additions & 0 deletions
29
examples/snippets/event-handler/appsync-graphql/advancedDebugLogging.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql'; | ||
import { Logger } from '@aws-lambda-powertools/logger'; | ||
import { | ||
correlationPaths, | ||
search, | ||
} from '@aws-lambda-powertools/logger/correlationId'; | ||
import type { Context } from 'aws-lambda'; | ||
|
||
const logger = new Logger({ | ||
serviceName: 'serverlessAirline', | ||
dreamorosi marked this conversation as resolved.
Show resolved
Hide resolved
|
||
logLevel: 'DEBUG', | ||
correlationIdSearchFn: search, | ||
}); | ||
const app = new AppSyncGraphQLResolver({ logger }); | ||
|
||
app.onQuery<{ id: string }>('getTodo', async ({ id }) => { | ||
logger.debug('Resolving todo', { id }); | ||
// Simulate fetching a todo from a database or external service | ||
return { | ||
id, | ||
title: 'Todo Title', | ||
completed: false, | ||
}; | ||
}); | ||
|
||
export const handler = async (event: unknown, context: Context) => { | ||
logger.setCorrelationId(event, correlationPaths.APPSYNC_RESOLVER); | ||
return app.resolve(event, context); | ||
}; |
42 changes: 42 additions & 0 deletions
42
examples/snippets/event-handler/appsync-graphql/advancedNestedMappings.ts
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { AppSyncGraphQLResolver } from '@aws-lambda-powertools/event-handler/appsync-graphql'; | ||
import { Logger } from '@aws-lambda-powertools/logger'; | ||
import type { Context } from 'aws-lambda'; | ||
|
||
const logger = new Logger({ | ||
serviceName: 'serverlessAirline', | ||
}); | ||
const app = new AppSyncGraphQLResolver({ logger }); | ||
|
||
type Location = { | ||
id: string; | ||
name: string; | ||
description?: string; | ||
}; | ||
|
||
const locationsResolver = async (): Promise<Location[]> => { | ||
logger.debug('Resolving locations'); | ||
// Simulate fetching locations from a database or external service | ||
return [ | ||
{ | ||
id: 'loc1', | ||
name: 'Location One', | ||
description: 'First location description', | ||
}, | ||
{ | ||
id: 'loc2', | ||
name: 'Location Two', | ||
description: 'Second location description', | ||
}, | ||
]; | ||
}; | ||
|
||
app.resolver(locationsResolver, { | ||
fieldName: 'locations', | ||
typeName: 'Merchant', | ||
}); | ||
app.resolver(locationsResolver, { | ||
fieldName: 'listLocations', // (1)! | ||
}); | ||
|
||
export const handler = async (event: unknown, context: Context) => | ||
app.resolve(event, context); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.