Skip to content

Commit b362e1b

Browse files
iartemievjosefaidt
andauthored
feat: add instructions for adding event api to backend (#8155)
* feat: add instructions for adding event api to backend * Apply suggestions from code review Co-authored-by: josef <[email protected]> --------- Co-authored-by: josef <[email protected]>
1 parent 2f1a163 commit b362e1b

File tree

1 file changed

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

1 file changed

+168
-4
lines changed

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

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

0 commit comments

Comments
 (0)