Skip to content
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

feat: add instructions for adding event api to backend #8155

Merged
merged 2 commits into from
Dec 9, 2024
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -89,15 +89,179 @@ export default function App() {
<>
<button onClick={publishEvent}>Publish Event</button>
<ul>
{myEvents.map((event, index) => (
<li key={index}>{JSON.stringify(event)}</li>
{myEvents.map((data) => (
<li key={data.id}>{JSON.stringify(data.event)}</li>
))}
</ul>
</>
);
}
```

## Connect to an Event API with an existing Amplify backend
## Add an Event API to an existing Amplify backend

Coming Soon
This guide walks through how you can add an Event API to an existing Amplify backend. We'll be using Cognito User Pools for authenticating with Event API from our frontend application. Any signed in user will be able to subscribe to the Event API and publish events.

Before you begin, you will need:

- An existing Amplify backend (see [Quickstart](/[platform]/start/quickstart/))
- Latest versions of `@aws-amplify/backend` and `@aws-amplify/backend-cli` (`npm add @aws-amplify/backend@latest @aws-amplify/backend-cli@latest`)

### Update Backend Definition

First, we'll add a new Event API to our backend definition.

```ts title="amplify/backend.ts"
import { defineBackend } from '@aws-amplify/backend';
import { auth } from './auth/resource';
// highlight-start
// import CDK resources:
import {
CfnApi,
CfnChannelNamespace,
AuthorizationType,
} from 'aws-cdk-lib/aws-appsync';
import { Policy, PolicyStatement } from 'aws-cdk-lib/aws-iam';
// highlight-end

const backend = defineBackend({
auth,
});

// highlight-start
// create a new stack for our Event API resources:
const customResources = backend.createStack('custom-resources');

// add a new Event API to the stack:
const cfnEventAPI = new CfnApi(customResources, 'CfnEventAPI', {
name: 'my-event-api',
eventConfig: {
authProviders: [
{
authType: AuthorizationType.USER_POOL,
cognitoConfig: {
awsRegion: customResources.region,
// configure Event API to use the Cognito User Pool provisioned by Amplify:
userPoolId: backend.auth.resources.userPool.userPoolId,
},
},
],
// configure the User Pool as the auth provider for Connect, Publish, and Subscribe operations:
connectionAuthModes: [{ authType: AuthorizationType.USER_POOL }],
defaultPublishAuthModes: [{ authType: AuthorizationType.USER_POOL }],
defaultSubscribeAuthModes: [{ authType: AuthorizationType.USER_POOL }],
},
});

// create a default namespace for our Event API:
const namespace = new CfnChannelNamespace(
customResources,
'CfnEventAPINamespace',
{
apiId: cfnEventAPI.attrApiId,
name: 'default',
}
);

// attach a policy to the authenticated user role in our User Pool to grant access to the Event API:
backend.auth.resources.authenticatedUserIamRole.attachInlinePolicy(
new Policy(customResources, 'AppSyncEventPolicy', {
statements: [
new PolicyStatement({
actions: [
'appsync:EventConnect',
'appsync:EventSubscribe',
'appsync:EventPublish',
],
resources: [`${cfnEventAPI.attrApiArn}/*`, `${cfnEventAPI.attrApiArn}`],
}),
],
})
);

// finally, add the Event API configuration to amplify_outputs:
backend.addOutput({
custom: {
events: {
url: `https://${cfnEventAPI.getAtt('Dns.Http').toString()}/event`,
aws_region: customResources.region,
default_authorization_type: AuthorizationType.USER_POOL,
},
},
});
// highlight-end
```

### Deploy Backend

To test your changes, deploy your Amplify Sandbox.

```bash title="Terminal" showLineNumbers={false}
npx ampx sandbox
```

### Connect your frontend application

After the sandbox deploys, connect your frontend application to the Event API. We'll be using the [Amplify Authenticator component](https://ui.docs.amplify.aws/react/connected-components/authenticator) to sign in to our Cognito User Pool.

If you don't already have the Authenticator installed, you can install it by running `npm add @aws-amplify/ui-react`.

```tsx title="src/App.tsx"
import { useEffect, useState } from 'react';
import { Amplify } from 'aws-amplify';
import { events, type EventsChannel } from 'aws-amplify/data';
import { Authenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import outputs from '../amplify_outputs.json';

Amplify.configure(outputs);

export default function App() {
const [myEvents, setMyEvents] = useState<Record<string, any>[]>([]);

useEffect(() => {
let channel: EventsChannel;

const connectAndSubscribe = async () => {
channel = await events.connect('default/channel');

channel.subscribe({
next: (data) => {
console.log('received', data);
setMyEvents((prev) => [data, ...prev]);
},
error: (err) => console.error('error', err),
});
};

connectAndSubscribe();

return () => channel && channel.close();
}, []);

async function publishEvent() {
await events.post('default/channel', { some: 'data' });
}

return (
<Authenticator>
{({ signOut, user }) => (
<>
<div>
<h1>Welcome, {user.username}</h1>
<button onClick={signOut}>Sign Out</button>
</div>
<div>
<button onClick={publishEvent}>Publish Event</button>
<ul>
{myEvents.map((data) => (
<li key={data.id}>{JSON.stringify(data.event)}</li>
))}
</ul>
</div>
</>
)}
</Authenticator>
);
}
```
Loading