Build Go Apps That Scale on AWS

Defining the API Gateway Routes



Build Go Apps That Scale on AWS

Check out a free preview of the full Build Go Apps That Scale on AWS course

The "Defining the API Gateway Routes" Lesson is part of the full, Build Go Apps That Scale on AWS course featured in this preview video. Here's what you'd learn in this lesson:

Melkey defines the routes for the API gateway. Each route has a resource name, the URL path, and the necessary methods like GET or POST. The route resources are added to the gateway with a new lambda integration.


Transcript from the "Defining the API Gateway Routes" Lesson

>> Let's go ahead and first define this infrastructure, and this is gonna be kinda the last piece of info we're gonna find here together right now in this workshop. So like I always like to do, let's just grab this, instead of AWS Lambda, it's gonna be awsapigateway. All right, cool.

Scroll all the way down. We can put it above the, you know what, let's put it below the GrantReadWrite table. It doesn't really matter, but let's just put it below just for keeping things consistent. We're gonna define API. We're gonna do awsapigateway.NewRestApi. You can see how many different resources available.

We're gonna do a NewRestApi. We're gonna pass in our stack, the main Lego piece. Hope you all didn't forget that. I'm gonna do jsii.String, give it some sort of identity you want, myAPIGateway, okay? So that's fine, and then obviously we need the specific resource props. I'm gonna do awsgateway.RestApiProps.

And if we dive into this, so this is where it kind of, I don't wanna say it gets more complicated cuz it really doesn't, but it just introduces a new aspect of web security and calling and CORS options and all of that. So this is where it kinda dances around that, but these props, again, I always wanna be consistent and say, if you are confused or don't know what props to put, obviously these resources are good, but also there's the docs here.

So everything that we've kinda gone through, I have a link to it here that I've kinda reserved. This would probably be available like in the repo or whatever. But for example, this is the AWS Lambda Construct, we can see those same properties that we use, the runtime handling code.

>> Is the API Gateway considered a reverse proxy?
>> It can be a reverse proxy, it can be but we actually are gonna be using it as a proxy here for our backend logic. So there's different ways you can configure your API gateway. You can just make it basically route things, and that's it.

But it can also act as a proxy for incoming requests and outputting your responses as well. Cool, and this API gateway is gonna kinda shift the way we start testing our deployments. And I'll show why we're gonna actually have a different style. But with all that being said, let's kinda go into this REST API props.

And there's a lot that we may want to look at but I think for right now, let's keep it kinda simple. Kinda keep it at a level that we want. So the very first one that's actually very important is the DefaultCorsPreflightOptions. If you've ever faced and dealt with CORS, you know how it's a pain.

Cross origin resource sharing, I think that's what CORS stands for. Yeah, yeah, yeah, why not? Again, I don't wanna act like an expert, I'm not in this field whatsoever, but basically from my understanding, it's the way to how different browsers or different domains speak with one another, right?

So a very, very basic example I can think of, let's say we have our frontend deployed into Next JSF and it's hosted on a specific domain. If that frontend application can talk to your backend, which is also separately deployed, right? If you have this kinda separation of concerns, and not everything is defined in Next, the communication between your frontend and your backend, both of them deployed individually.

The connection between them is CORS, or CORS regulates how they can talk to each other. It's a pain, please, I don't wanna get into CORS here, but let's go and head and populate our props here, our struck. So we're gonna have AllowHeaders. Now, this important field, one thing to know, this is JI strings, because this is basically gonna be a list of strings, not just an individual string.

And this is gonna basically say, for incoming requests, do you have the header I expect, we're only gonna have two. The first one is the most classic, the content type, and that's typically gonna be application JSON, right? If you make a request, you're gonna have to put this head off as JSON.

And second one is authorization. Okay, we're not gonna use authorization just yet. But remember that access code badge thing I mentioned way way long ago, that's what's gonna come into play. So now we have this AllowHeaders, the next one is gonna be AllowMethods. It's gonna be the same thing, jsii.Strings, and this is what methods are we gonna allow request to call.

Can you post, can you get, can you put, can you delete, the options, all of that is what we can define here. I'm just gonna make them all even though we're only gonna be using two, so go ahead and do that. Get, post, delete, put, and options. Cool, okay, and the most dreaded one of them all, the final boss, Is this AllowOrigins.

If you've seen that error message on your computer, it's like CORS preflight option. This is this origin kind of source. I'm just gonna keep it 100 with you all, we're gonna do a wild card, all right? We're not gonna open that Pandora's box just yet. So we're gonna do AllowOrigins as just everything coming in.

Again, it's all gonna be controlled, and nothing's gonna be too public-facing, so there's not really a concern here. And we'll tear all this down at the end of this workshop, okay? Really, this is all you need. At a super, super high level, this is all you need, and then this gets slapped onto your backend.

And I'm gonna show you how this is done, but you can do a few other things. One is, I personally deploy options, and the only property I like to deploy options is logging. Because again, if you don't have the right preflight options, if your CORS are not set correctly, you wanna have a good way to log all that info.

So we can do awsapi StageOptions and then just put LoggingLevel, and it's gonna be AWS MethodLoggingLevel_INFO. Cool. All right, now in this snapshot of time, if we deploy this, nothing's gonna change. Cuz again, remember the same thing with the table, it all comes down to Lego pieces. The table needs to know that our lambda can invoke it.

Just like our API gateway needs to know where it's gonna send request to, and that's the lambda. So we're gonna have to integrate those two together. So all at the bottom here, we're going to create a new variable integration, okay? And it's gonna be basically awsapigateway, I'm gonna put NewLambdaIntegration, okay?

Cuz sometimes your backend isn't a lambda. Sometimes it could just be something else. So we're gonna do a new lambda integration. And the first thing that we're gonna pass it in is this myFunction. And right now, again, it's not doing anything. It's just a variable, it still has no binding back.

If you look at this, this has no interaction with line relative 11, where we have that API unused variable, right? So still, we truly haven't done anything, we just declared a new integration. But now, what I wanna do is define the routes, and this is where the integration comes into play.

So we're gonna do a registerResource. The registerResource is fine. I was gonna do registerRoute but it is what it is. Then we'll do API, which is the gateway that we were defining. We're gonna do route, okay? And here we're gonna add a resource, AddResource. And the first parameter into this AddResource is the path for the invocation from the requests.

So this defines local hosts, let's say 3000/register. This is where that /register part gets defined. So we're gonna do, I almost got caught with that, jsii.String, and you put register, okay? We're gonna no additional parameters. And again, you can put the wildcard or something like register/id, you can do this, right?

And then parse that ID from the request. There's no need for us to do it here, but that's just how you would go about doing it if that's something you need to do. Cool, now, we'll do registerResource and we're gonna do AddMethod. And this basically defines, okay, what method, is this a GET method, is it a POST method, could be both, could be a ton.

We're in jsii.String and this is gonna be a POST. And now this is where you pass in integration. So now we've completed that loop. Now we have the API gateway. We have this integration between API gateway, knowing hey, this can be new lambda integration. AWS is gonna do some magic behind the scenes for us.

And then we're registering a route, which is /register, to the integration, to that lambda to gateway bridge. Cool, while we're here, we're gonna actually make the next route, so you can go ahead and just copy this and paste it. And instead of registerResource, let's do loginResource, everything else is gonna stay the same.

Instead of register, I'm gonna put login. It's still gonna be a POST, and again just make sure that it's login here. Cool, any questions on this? Any questions at all? Yes.
>> I mean, this is all preference. So this function is getting pretty big. Is it common to break these out into smaller functions to set up your API, this function set up your, whatever, this function?

>> You're talking about the stack definition here, right?
>> Yeah.
>> So truthfully, stacked functions are pretty long because they are pretty much constructed as is where you have everything kind of defined. The layer of abstraction that's kind of been implemented, because, I agree, it's kind of getting gnarly, is you could separate and have almost your just internal library where you define snippets of the construct, right?

So you know how we're defining the lambda fully? You can actually have a construct that's just the lambda definition and then bring that in into your stack definition. So there is a layer of abstracting it if you want, but typically, again preference but you do see pretty crazy stack functions defined.

Yes, question.
>> And thanks to all cliffs in the chat for integration as a typo in your code there.
>> It does. Integrate, yes, nice. I also can't spell. Is that how you spell integration? Okay, [LAUGH] sweet.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now