Skip to content

Commit 230cbd9

Browse files
committed
feat: add instructions for adding event api to backend
1 parent 9e1687c commit 230cbd9

File tree

1 file changed

+171
-4
lines changed
  • src/pages/[platform]/build-a-backend/data/connect-event-api

1 file changed

+171
-4
lines changed

src/pages/[platform]/build-a-backend/data/connect-event-api/index.mdx

Lines changed: 171 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -89,15 +89,182 @@ export default function App() {
8989
<>
9090
<button onClick={publishEvent}>Publish Event</button>
9191
<ul>
92-
{myEvents.map((event, index) => (
93-
<li key={index}>{JSON.stringify(event)}</li>
92+
{myEvents.map((data) => (
93+
<li key={data.id}>{JSON.stringify(data.event)}</li>
9494
))}
9595
</ul>
9696
</>
9797
);
9898
}
9999
```
100100

101-
## Connect to an Event API with an existing Amplify backend
101+
## Add an Event API to an existing Amplify backend
102102

103-
Coming Soon
103+
This guide walks through how you can add an Event API to an existing Amplify backend.
104+
We'll be using Cognito User Pools for authenticating with Event API from our frontend application.
105+
Any signed in user will be able to subscribe to the Event API and publish events.
106+
107+
Before you begin, you will need:
108+
109+
- An existing Amplify backend (see [Quickstart](/[platform]/start/quickstart/))
110+
- Latest versions of `@aws-amplify/backend` and `@aws-amplify/backend-cli` (`npm i @aws-amplify/backend@latest @aws-amplify/backend-cli@latest`)
111+
112+
### Update Backend Definition
113+
114+
First, we'll add a new Event API to our backend definition.
115+
116+
```ts title="amplify/backend.ts"
117+
import { defineBackend } from '@aws-amplify/backend';
118+
import { auth } from './auth/resource';
119+
// highlight-start
120+
// import CDK resources:
121+
import {
122+
CfnApi,
123+
CfnChannelNamespace,
124+
AuthorizationType,
125+
} from 'aws-cdk-lib/aws-appsync';
126+
import { Policy, PolicyStatement } from 'aws-cdk-lib/aws-iam';
127+
// highlight-end
128+
129+
const backend = defineBackend({
130+
auth,
131+
});
132+
133+
// highlight-start
134+
// create a new stack for our Event API resources:
135+
const customResources = backend.createStack('custom-resources');
136+
137+
// add a new Event API to the stack:
138+
const cfnEventAPI = new CfnApi(customResources, 'cfnEventAPI', {
139+
name: 'my-event-api',
140+
eventConfig: {
141+
authProviders: [
142+
{
143+
authType: AuthorizationType.USER_POOL,
144+
cognitoConfig: {
145+
awsRegion: customResources.region,
146+
// configure Event API to use the Cognito User Pool provisioned by Amplify:
147+
userPoolId: backend.auth.resources.userPool.userPoolId,
148+
},
149+
},
150+
],
151+
// configure the User Pool as the auth provider for Connect, Publish, and Subscribe operations:
152+
connectionAuthModes: [{ authType: AuthorizationType.USER_POOL }],
153+
defaultPublishAuthModes: [{ authType: AuthorizationType.USER_POOL }],
154+
defaultSubscribeAuthModes: [{ authType: AuthorizationType.USER_POOL }],
155+
},
156+
});
157+
158+
// create a default namespace for our Event API:
159+
const namespace = new CfnChannelNamespace(
160+
customResources,
161+
'cfnEventAPINamespace',
162+
{
163+
apiId: cfnEventAPI.attrApiId,
164+
name: 'default',
165+
}
166+
);
167+
168+
// attach a policy to the authenticated user role in our User Pool to grant access to the Event API:
169+
backend.auth.resources.authenticatedUserIamRole.attachInlinePolicy(
170+
new Policy(customResources, 'AppSyncEventPolicy', {
171+
statements: [
172+
new PolicyStatement({
173+
actions: [
174+
'appsync:EventConnect',
175+
'appsync:EventSubscribe',
176+
'appsync:EventPublish',
177+
],
178+
resources: [`${cfnEventAPI.attrApiArn}/*`, `${cfnEventAPI.attrApiArn}`],
179+
}),
180+
],
181+
})
182+
);
183+
184+
// finally, add the Event API configuration to amplify_outputs:
185+
backend.addOutput({
186+
custom: {
187+
events: {
188+
url: `https://${cfnEventAPI.getAtt('Dns.Http').toString()}/event`,
189+
aws_region: customResources.region,
190+
default_authorization_type: AuthorizationType.USER_POOL,
191+
},
192+
},
193+
});
194+
// highlight-end
195+
```
196+
197+
### Deploy Backend
198+
199+
To test your changes, deploy your Amplify Sandbox.
200+
201+
```bash title="Terminal" showLineNumbers={false}
202+
npx ampx sandbox
203+
```
204+
205+
### Connect your frontend application
206+
207+
After the sandbox deploys, connect your frontend application to the Event API.
208+
We'll be using the Amplify Authenticator to sign in to our Cognito User Pool.
209+
210+
If you don't already have the Authenticator installed, you can install it by running `npm i @aws-amplify/ui-react`.
211+
212+
```tsx title="src/App.tsx"
213+
import { useEffect, useState } from 'react';
214+
import { Amplify } from 'aws-amplify';
215+
import { events, type EventsChannel } from 'aws-amplify/data';
216+
import { Authenticator } from '@aws-amplify/ui-react';
217+
import '@aws-amplify/ui-react/styles.css';
218+
import config from '@/amplify_outputs.json';
219+
220+
Amplify.configure(config);
221+
222+
export default function App() {
223+
const [myEvents, setMyEvents] = useState<Record<string, any>[]>([]);
224+
225+
useEffect(() => {
226+
let channel: EventsChannel;
227+
228+
const connectAndSubscribe = async () => {
229+
channel = await events.connect('default/channel');
230+
231+
channel.subscribe({
232+
next: (data) => {
233+
console.log('received', data);
234+
setMyEvents((prev) => [data, ...prev]);
235+
},
236+
error: (err) => console.error('error', err),
237+
});
238+
};
239+
240+
connectAndSubscribe();
241+
242+
return () => channel && channel.close();
243+
}, []);
244+
245+
async function publishEvent() {
246+
await events.post('default/channel', { some: 'data' });
247+
}
248+
249+
return (
250+
<Authenticator>
251+
{({ signOut, user }) => (
252+
<>
253+
<div>
254+
<h1>Welcome, {user.username}</h1>
255+
<button onClick={signOut}>Sign Out</button>
256+
</div>
257+
<div>
258+
<button onClick={publishEvent}>Publish Event</button>
259+
<ul>
260+
{myEvents.map((data) => (
261+
<li key={data.id}>{JSON.stringify(data.event)}</li>
262+
))}
263+
</ul>
264+
</div>
265+
</>
266+
)}
267+
</Authenticator>
268+
);
269+
}
270+
```

0 commit comments

Comments
 (0)