brefphp / bref

Serverless PHP on AWS Lambda
https://bref.sh
MIT License
3.1k stars 367 forks source link

Replace API Gateway with CloudFront + Lambda Function URLs everywhere in Bref? #1625

Open mnapoli opened 1 year ago

mnapoli commented 1 year ago

Right now, Bref's docs/examples/defaults deploy:

graph LR;
API(API Gateway)-->Lambda(Lambda);

For websites, it deploys:

graph LR;
CloudFront-->API(API Gateway)
API-->Lambda(Lambda);

Lambda Function URLs are great to replace API Gateway. However they don't have custom domains. That means you need CloudFront (for the custom domain). That works for websites right now (we already have CloudFront there), but not APIs (which don't use CloudFront).

How about dropping API Gateway entirely (for the docs/examples, Bref would still work with it of course) and go full Lambda Function URLs + CloudFront.

We would have 3 different scenarios:

graph LR;
CloudFront-->Lambda(Lambda Function URL);

Pros:

Cons:

Summary:

Running APIs and websites might be simpler, faster and cheaper!

Am I missing anything? Feedback is welcome 🙏

shadowhand commented 1 year ago

A couple of questions:

  1. Since websites with a custom domain would now effectively have 2 URLs (Lambda Function URL, CloudFront custom URL), would Bref provide a helper that would let me block direct access to the function URL, so that only the custom domain/URL is used?
  2. Would it make sense to provide "skip API Gateway" as a feature toggle, so that users could choose to keep the current behavior?
mnapoli commented 1 year ago

@shadowhand regarding question 1, I listed it in the "Cons" (but edited early today, so you might have missed it):

The Lambda Function URL would be publicly (on top of the CloudFront URL), making it private would require some more effort (custom header or using Lambda@Edge)

To expand on the first option, here are more info: https://stackoverflow.com/a/72271684/245552

I'm not sure if that should be a native Bref feature 🤔 Deploying lambda@edge would for sure not be, because it's complex and it sucks. But maybe the header thing…

Would it make sense to provide "skip API Gateway" as a feature toggle, so that users could choose to keep the current behavior?

Existing users wouldn't be impacted. Their serverless.yml wouldn't change. Only the Bref docs would change, but the main difference is about replacing events with url: true, so I don't think there would be too much confusion in the docs.

The server-side-website Lift construct would still work, it will (should? that might not be the case currently but I can work on that) detect whether there's an API Gateway or a Function URL and automatically use it as the source of the CloudFront distribution.

spaceemotion commented 1 year ago

I only recently learned about function URLs myself (because they also allow streaming responses - which is great for AI-powered applications!). However three questions came up:

  1. Does the current setup always link to $LATEST or does it handle switching to the new version internally? Sometimes things can go wrong and you have to go back a version
  2. Would rate-limiting be done via CloudFront in this case? Even if lambda can support millions of requests, I don't need to have more than 5k requests/sec for most smaller apps.
  3. Api Gateway also offers a firewall, does AWS WAF work the same when it's just CloudFront?
mnapoli commented 1 year ago

Very good points!

1. Does the current setup always link to $LATEST or does it handle switching to the new version internally? Sometimes things can go wrong and you have to go back a version

I'm not sure it could do what you may want. Here are what the docs say:

You can apply function URLs to any function alias, or to the $LATEST unpublished function version. You can't add a function URL to any other function version.

You could use aliases, but I don't think the Serverless Framework does anything clever. But you may achieve that yourself?

Given most Bref users don't use Lambda versions at all, that's not something I intend to support for getting started templates/docs. Users can grow into these features by themselves if they want this, Bref is compatible with whatever Lambda can do.

2. Would rate-limiting be done via CloudFront in this case? Even if lambda can support millions of requests, I don't need to have more than 5k requests/sec for most smaller apps.

Good point, here are the Lambda docs:

Your function's maximum request rate per second (RPS) is equivalent to 10 times the configured reserved concurrency. For example, if you configure your function with a reserved concurrency of 100, then the maximum RPS is 1,000.

Whenever your function concurrency exceeds the reserved concurrency, your function URL returns an HTTP 429 status code. If your function receives a request that exceeds the 10x RPS maximum based on your configured reserved concurrency, you also receive an HTTP 429 error. For more information about reserved concurrency, see Configuring reserved concurrency.

It seems you can easily limit the RPS, so it seems to do the job, right? (at least as good as API Gateway?)

3. Api Gateway also offers a firewall, does AWS WAF work the same when it's just CloudFront?

WAF works with CloudFront (and it's even better because AWS Shield Advanced only supports CloudFront, not API Gateway).

GrahamCampbell commented 1 year ago

WAF works with CloudFront

Also on API gateway v1, I think. Though v1 does not have great performance or pricing.

kevincerro commented 11 months ago

I'm interested in this because ApiGatewayV2 is not supported in eu-south-2 (Spain) region. If any help is needed please tell me

mnapoli commented 11 months ago

@kevincerro the main thing we need to have is make https://github.com/getlift/lift/blob/master/docs/server-side-website.md use Function URL if API Gateway is not used (it requires code changes in Lift).

For the documentation I can take care of that 👍 (but it's currently blocked by the Lift issue).

kevincerro commented 10 months ago

@kevincerro the main thing we need to have is make https://github.com/getlift/lift/blob/master/docs/server-side-website.md use Function URL if API Gateway is not used (it requires code changes in Lift).

For the documentation I can take care of that 👍 (but it's currently blocked by the Lift issue).

I'm going to try to take care of this

kevincerro commented 10 months ago

Draft PR here, some improvements are needed regarding configuration logic https://github.com/getlift/lift/pull/368

honktang commented 10 months ago

I'm interested in this because ApiGatewayV2 is not supported in eu-south-2 (Spain) region. If any help is needed please tell me

function urls is not supported either. https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html

kevincerro commented 10 months ago

I'm interested in this because ApiGatewayV2 is not supported in eu-south-2 (Spain) region. If any help is needed please tell me

function urls is not supported either. https://docs.aws.amazon.com/lambda/latest/dg/lambda-urls.html

Yes I know, I hope that AWS will add lambda url to eu-south-2 soon. In the meantime I'm using eu-west regions.

mnapoli commented 4 months ago

I know there hasn't been progress here. I'm posting two updates in favor of using FURL over API Gateway v2: