yarbsemaj / sveltekit-adapter-lambda

An adapter to build a SvelteKit app into a lambda ready for deployment with lambda proxy via the Serverless Framework or CDK.
https://www.npmjs.com/package/@yarbsemaj/adapter-lambda
MIT License
77 stars 16 forks source link

How does SSR function gets triggered? #21

Closed lukaskoeller closed 1 year ago

lukaskoeller commented 1 year ago

First of all, neat stuff you created there! 🀩

I am trying to implement it using Pulumi instead of serverless (still quite new to all of it).

I managed to upload prerendered and assets to s3, create a cloudfront distribution and connect it with the edge function. Working so far βœ…

Now I wanted to deploy the SSR function (build/server/serverless.handler). I just wonder though, how and when this function gets triggered? I see you create an URL for it (serverless.yml:51), so I assume its called via an http request (?) but this url of course doesn't exist at build time of the svelte app. Your blog entry indicated an api gateway in between, though can't see you defining it in your serverless.yml.

Would you be so kind to point me into the right direction?

yarbsemaj commented 1 year ago

Hi @lukaskoeller, thank you for your interest in my project!

The blog post is a bit out of date, i'll get on updating that. Previously it did use an API gateway, but since Amazon added support for Lambda function urls this has no longer been necessary as thus to save cost I removed the API gateway.

When there was an API gateway, serverless took care of creating it for you, you just specify the event (in this case a http request), the path and the function you want to call and serverless did job of creating the api gateway, route, IAM roles etc.

As for how its called now, you are correct that it's just a http request, if you hit the function URL you will get back the HTML (or JSON etc..) of the path you add to the end of the url. The path, query params and headers are proxied through by cloudfront onto that http call with logic inside the lambda extracting then and passing them to your svelte kit app, response data is sent in a standard format and amazon magically adds this onto the response back from the function url. The function url of the SSR lambda is the default origin of the cloudfront with origin been changed by the edge function if the file is on the manifest of files in S3.

I hope that cleared everything up for you.

lukaskoeller commented 1 year ago

Many thanks @yarbsemaj, instant reply 😍

I think I got it. By default cloudfronts origin is the lambda function url. But if the edge function detects a static asset it instead routes to the s3 origin?

(Will try that later and share a code excerpt for people using pulumi too)

lukaskoeller commented 1 year ago

A more generic question. Wouldn't it be possible to modify the build to separate ssr stuff and static stuff in a way that static assets follow a certain path pattern (e.g. always static/**/*) and use path pattern with two origins to route to the S3 (path includes static) or S3. Thus, getting rid of the Lambda@Edge?

yarbsemaj commented 1 year ago

You could, but then that would remove the option of having any static assets outside the static folder so things like robots.txt, or .well-known, although you could add exceptions for those file. However, it also would remove the option for serving pre-compiled pages from S3 for large sites, as there is a limit on the number of rules you can add to a cloudfront. I have it build like this so anyones site should just work without having to modify the build process or worry about site size.

lukaskoeller commented 1 year ago

That's a good point, makes totally sense this way. Thanks for the explanation!

lukaskoeller commented 1 year ago

Okay I hope one last thing πŸ˜…

I made everything working (thanks again). Though, one thing is different. I had to configure the originProtocolPolicy with http-only, instead of https-only how you did it.

Concerning that, I found the following in the AWS Docs:

HTTP only is the default setting when the origin is an Amazon S3 static website hosting endpoint, because Amazon S3 doesn’t support HTTPS connections for static website hosting endpoints. The CloudFront console does not support changing this setting for Amazon S3 static website hosting endpoints.

The reason I configured static website hosting was due to the following in the AWS Docs:

A custom origin. A custom origin is any origin that is not an Amazon S3 bucket, with one exception. An Amazon S3 bucket that is configured with static website hosting is a custom origin.

With https-only I was constantly getting 502 Bad Gateway on all S3 Resources. Now, another effect of http-only seems to be SSR, because all requests made to the SSR Lambda are now stuck in (pending) πŸ˜…

How do you make that work?

yarbsemaj commented 1 year ago

I'm not using static site hosting for my assets, I just rewrite the origin to the file in the bucket, and have bucket files public read.

lukaskoeller commented 1 year ago

Ok the problem is using dot notation (.) for the bucket name. AWS has wildcard SSL certificate for *.s3.amazonaws.com which doesn't apply for buckets with dot notation. Hence, s3 is served via http instead of https. Renaming the bucket using dash (-) worked just fine.