Main

Event-driven architectures will NEVER be the same!

See how to use AWS EventBridge to directly invoke AppSync mutations. Great for real-time apps. We cover event buses, rules, IAM policies to enable the integration, mutations, subscriptions, sending test events, and live demos. 00:00 Intro 00:31 EventBridge + AppSync 00:53 Invoking Mutations 01:14 Creating Resources 01:34 IAM Setup 02:04 Appsync Schema 02:30 Publish Mutation 03:14 Resolver Code 03:35 GraphQL Schema 03:50 Schema Overview 04:06 Main Mutation 04:30 Cognito Setup 04:59 Event Rule Details 05:20 Event Bus Setup 05:42 Event Bridge Rule 06:34 CloudFormation Rule 06:47 Rule Criteria 07:10 Target Details 07:40 Payload Mapping 08:08 Variable Input 08:22 Cognito User Pool 08:42 Identity Pool 09:11 Generated Types 09:44 Importing Services 10:28 Stack Resources 10:51 Endpoint ARN 11:10 Deploying Stack 11:38 Testing End-to-End 12:08 Creating User 12:37 Subscribing 13:04 Fixing Login 13:23 Running Subscription 13:43 Sending Event 14:22 Event Payload 14:59 Seeing Real-time Data 15:37 Summary repo: https://github.com/focusOtter/eventbridge-target-appsync/

Focus Otter

1 month ago

So it turns out event driven applications are really great because they allow for application one to take an event and throw it off into the ether so that other applications can then take that message and do whatever they want with it. And really they're just passing messages back and forth between each other. The problem arises when one of those applications takes that message and needs to showcase some data in real time. Now, in the past, app applications have gone around this by doing somethi
ng like polling, right? But let's face it, that's a little bit dated. And honestly, we can do better. So in this video, we're going to talk about a brand new feature where Eventbridge now has direct support for Appsync. This allows Eventbridge to call an appsync API and invoke a mutation. What's cool about that, you ask? Well, whenever a mutation gets sent off, client side applications can subscribe to that message via a websocket, which comes out of the box with Appsync. Now on this channel, we
talk a lot about how to build out applications with Appsync, but tying these two together is really powerful. Let's go ahead and boot up a new CDK project, and I'll show you just how easy it is to get started. Okay, so let's get something going on. We're going to create a brand new project which we're going to call Eventbridge. Invoke Appsync, and once we're inside of here now, we can create a brand new CDK project. So CDK init. And then we're going to, of course, write this all in typescript.
And once this gets all done, I'm actually going to open this up in vs code, so that way we can start coding right away. Okay, so as I'm cleaning this up, let's kind of think about this a little bit. We need the ability for Eventbridge to invoke an Appsync API as a direct target. Right now, currently, the L two construct for Eventbridge rules isn't supported just yet, but the L one construct is following cloud formation and that is supported. So we're going to have to drop down at some point to g
et that taken care of. Now, if you've seen any of my other videos, you know how I like to structure my content, where we can create a new file and it's going to be inside of this folder, where it's going to be our API. And then we'll do appsync TS. Creating an appsync API is fairly simple, so I'm going to go ahead and paste in some code here and then we can talk about it. But nothing too crazy is going on. We have our imports, of course, but the meat of all of things really comes down to creatin
g our API. You see that the primary method for authentication and authorization is going to be with this IAM configuration, but we are going to additionally have the ability to have a kanito user pool on our schema as well. We're also going to log out any additional details coming from our resolvers. But the star of the show is going to be this. Down here we're not going to have a data source. You can definitely check out my other videos if you want to see how to store data inside of Dynamodb, e
t cetera. But really eventbridge is going to be calling this push message resolver. And from here this mutation is going to get invoked and we want to make sure that a subscription gets taken place. And this resolver is coming from this code called publish message JS. And again, this is really a, it's a none resolver. So no data is actually going to be stored anywhere. I'm going to call this publish message JS just like that. I'll show you what this resolver code looks like. I still love the abi
lity to have these functions look like sort of lambda functions, but really they're just passing data between AWS services, which is really cool. Now we're going to log out the context just for good measure. And then because it is a none type data source, we just take the payload and we're passing it on to whatever. That's because the star of the show isn't really this resolver ability. Again, it's going to be eventbridge invoking this app sync mutation to begin with. Now this is of course assum
ing that we have a schema in place. So let's go ahead and create that schema graphql, it's just like that. And then inside of here we can put in our actual schema code. Okay, so there we go. Now, a couple of things. One, clients can only subscribe to mutations in appsync. Two, per the graphql spec. So not an appsync thing, but graphql in general. Every schema needs at least one query. Now, we don't really need a query in this example, so I'm just going to call this like a no op. There's no opera
tion here, but our mutation is actually really interesting. We're going to publish a message and one of the arguments that it takes is the message itself. And then this at AWS underscore IAM directive effectively means protect this operation by only allowing someone with the correct IAM permissions to call this. You'll see how we set that up in just a moment. Next up is our subscription. Now, we don't need to create a resolver for this, it'll automatically publish the message. You can create a r
esolver to do advanced things like filtering, but at the same time, all we really care about is the ability for a signed incognito user to have the option to call this operation. And we are going to subscribe to this publish message from Eventbridge Mutation. Just like that. Now, before we actually start invoking this inside of our stack file, which is currently empty, let's get the eventbridge portion of things set up. Now, following my own personal convention here, we're going to create a new
file and it's going to be in this folder called choreography. And inside of this folder now we can put in Eventbridge Ts. Cool. Okay, so I pasted in the code and I deleted some of the stuff that I had already set up just so that we can walk through this sort of in step here. So in this choreography file, we have Eventbridge, right? And we're going to create a new event bus. You can of course use the default bus, but for applications, I just personally like to use separate buses for them. In any
case, creating a new bus for Eventbridge is super, super easy. As you can see here, we're going to pass in the bus name. This will get instantiated. And the whole idea here is that we're going to put a message on this bus and a rule which is really going to do all the work here. And a rule is going to listen to some kind of data that we tell it to is important and invoke a target. So we have buses, we have rules that get invoked when a certain payload matches a criteria, and then we have the tar
gets that get invoked by that rule. So for us, we want to give it the permissions to invoke an appsync API as a target, specifically that mutation. And we're going to do so just like this. We're going to create a policy. It's going to be the Arn of our appseeek API, and then the type that we're listening for is going to be. And then I'm saying any mutation, but you can of course lock that down so that it's just our publish message to EB mutation as well. We're going to take that policy and assig
n it to a brand new role. Is what we're creating right here and from here. Just recall that currently the l two construct for an eventbridge rule doesn't support absync as of yet. So we just drop down to the l one construct and we do so like this. We create our rule. I'm just going to call it something basic like my cloudformation rule. We give it the bus name. We give our rule a name and then this is the important part. What are you trying to listen for in the event pattern? All we're saying is
anything that comes in with this thing called sample source, if you have an event come in on this bus and it has a source called sample source, I'm going to invoke the targets that are listed here. What targets are listed? It's going to be this appsync API. So one of the things that tripped me up is that it's not the appsync API arn. There's a separate endpoint arn that you want to pass in as well. All good. We give it the role so that way it has the right permissions and we give it the operati
on that we want it to call. Now keep in mind, this payload, this message payload that we send to Eventbridge is going to have objects all over the place and nested objects and a bunch of data inside of this payload, right? We're going to say, I want you to take the event payload, grab the detail object and pull off the message. Now when we send a message to Eventbridge, we're going to stick in a message string inside of this detail object just like this. We're going to say, take that and put it
on a brand new object where that message is living right at the top. From there we create a template that we're passing over to our appsync API in this stringified object where it's a message key and then our message. And it's like, why are we doing that? If you remember, our schema is looking for the ability to have a message pass in. And this is how we're going to be passing this as a variable to our GraphQl API. So we have that in place. That's what's getting taken care of right here. Last th
ing we need to do is just subscribe to this message. So we're going to create a really quick cognito service here. So I'm going to say Auth Cognito TS. And I'm not going to spend too much time on this because you've seen me do this a bunch of other times in other videos. But let's go ahead and bring in some cognito APIs. And then we'll also bring in the l two construct, which is currently alpha but hopefully released on main soon. So that way we have an easy way to create an identity pool. The t
en second whirlwind is that we're coming down here creating a user pool. We're giving it a name, allowing our users to sign in with email, and then we have a user pool client in case we ever wanted to add in social auth. And then lastly we have identity pools, so that way our users have the right permissions to be authenticated. Now one of the things that you might have noticed is that when we went over to our Eventbridge API, we're saying I'm going to pass in a Graphql prop of Graphql operation
. We haven't created that yet. So how do we get these types available or these operations automatically crafted for us so we don't have to maintain them simply enough? I can come over to our lib API directory, hit enter, and now we can have the AWS amplify Cli do that. For me, I'm simply going to say MpX at AWS amplify slash Cli, and then I'll say code Gen and add. Now this is going to look at my schema and ask me questions on how I want this to be created. That's of course if I put in actually
code Gen and not code in. So we're going to fix it. And now we'll go ahead and run that command. Now what's really cool is that I get the ability to add this in, react, and get my types automatically generated for me. And we can say yes to basically all of these commands here. Now when that gets done, I have this source directory and inside of it I have my graphql and then my mutation section right here. This is what I need to pass to my eventbridge rule. So that way it has the right operation.
Here you can see right up top this props graphql operation is going to be that mutation that we told it to listen to. So with all that in place, we have a way for an event bus to have a rule applied. That rule is going to invoke our appsync API and then from there we can test things out by subscribing to it. I'm going to head over to our stack file and bring in these services here. Now that I have this code copied in, I'm going to fix some of these imports. So that way vs code can find the right
paths to all of these services that we're creating. Keeping in mind that I am having to drop down to the one construct of our GraphQl API just so that I can get the arn for our graphql endpoint. You can see that part right there. What I love is that that is it. We have our services in place. So with that in place, I'm actually ready to go ahead and deploy this. So to open up my terminal and I'm going to bring in my CDK deploy command, of course, passing in my profile of focus auto sandbox. Now
what's cool is that I can view and test this all in the AWS console. And I'll show you how to do that in just a moment here. So looking over some of the IAM changes here, you can see that we have appsync annotations set up right down here, so that's being applied. We also have the permissions set for our identity pool set up right here with our authenticated role and then a bunch of other policies as well. And feel free to go ahead and check those out. I am going to say yes to deploying this and
then I'll meet you in the AWS console where we can check and verify that this all worked. So to test this out, I'm going to head over to Cognito and first and foremost, I'm just going to create a user. And this user is going to be not really useful in this application, but just to show you how someone can subscribe to the data in a front end application if they were to use something like the amplify libraries. So we're going to send an email and let's just go ahead and call this person focus ot
ter down here. We'll go ahead and give it an email address. Next up, we'll mark it as verified so we don't have to do that and we'll have it automatically generate a password for us. Now, this got created. All I'm going to do on my end is grab this passcode from my email and then we can use this in the appsync console just to get a user set up and verified in our account. So I'm going to head there to the appsync console, grab our API here, this invoke appsync API, and then now we can go over to
our query section to create and subscribe to some data. I'm going to choose subscription here and I need the ability actually, before doing any of that. Let's just go ahead and get our user. Pull in here, get our user logged in and select our client id. We call this focus otter. And what I love is that by passing in this temporary password when I click on login, it prompts me to have a user automatically saved. Now I must not have copied this over correctly. Looking at my email, looks like I di
d have an extra space in there. So that should get fixed here. There we go. And then now I can log in. Let's ask somebody to change my password. I'm going to get something in here. Cool. Now I can log into the account and this person is all set and good to go. All they are going to do on this application is just click on subscription. So this person is now going to our subscription, adding the subscription and then clicking on here. Now they can go ahead and run it. And now they're subscribing.
Nothing crazy is going on so far. However, over in this browser tab, let's go to Eventbridge. And this is simulating another application, putting an event on our event bus. So let's go to event buses and we want to be able to send events and we'll select the nondefault bus here. It's going to be this app sync or sorry, eventbridge invoke appsync and then the source, if you recall it is going to be. Let's look back in our application here, just so I can show you where it's at. If you go to Eventb
ridge, the source that we're looking for is sample source. So over here I'm going to put just that. The message type doesn't really matter because we're not filtering on it. So I'm just going to say hello. And here's the really important piece. We need to specify the JSON payload that is going to be passed in. Now I'm just going to say something simple like here's our message and this is going to be hello YouTube. And then of course a friendly reminder to like and subscribe if you found this vid
eo helpful. Now all this, what we should have over here on the left hand side, I'm going to bring these two together, is our API, is eventbridge should be talking to our API so that way it can bring that message over to our application here. Now, just to make this a little bit more visible, I'm going to make some room here by moving this ever oh so gently over. And when I come down here to send this event, look what happens here. I'm going to click send. And just like that again, this is a messa
ge being passed to an event bus, that bus is then having a set of rules applied to it. And the rule that we set up is that anytime there is a source called sample source, invoke my appsync API mutation and we are subscribing to that mutation via a websocket right here in the console. You can see that data show up just like so. This is crazy powerful because these are two completely decoupled applications, and I hope I presented that in a way where it makes sense of all the possibilities that thi
s now unlocks in terms of all the real time data capabilities that you have now at your disposal. Note that we didn't use a single lambda function. There is no polling, no other mechanism aside from tried and true purpose built AWS services. Okay, so there was a quick example of this new feature. I hope you enjoyed it, but definitely keep in mind that this is only the beginning. I'm going to be pumping out a bunch of content related to this release because I just personally find it super interes
ting. But if there is anything in particular that you would like to see, let me know on the channel here. Drop a comment and I'll be sure to reply and let you know that's going to make it onto the next focus auto lineup. As always, happy coding and I'll catch you all next time.

Comments