Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RFC: state of Serverless Next.js and next steps #777

Closed
dphang opened this issue Nov 7, 2020 · 11 comments
Closed

RFC: state of Serverless Next.js and next steps #777

dphang opened this issue Nov 7, 2020 · 11 comments

Comments

@dphang
Copy link
Collaborator

dphang commented Nov 7, 2020

Hi all!

I hope you are having a great weekend. I just wanted to take some time to give some updates on the current state of Serverless Next.js. This is a long post - TL;DR on bottom if you want. Ever since I've started using this early this year, and contributing just a few months back, we as a community have accomplished, as of version 1.18 or 1.19 alpha:

  • Stability improvements: for example, we added multiple end-to-end tests that deploy a real Lambda@Edge for both the current-minor and previous-minor Next.js versions, pinned dependencies, enabled security updates (automated dependency updates are a WIP via Renovate), and added a bunch more unit test coverage for the handler code.
  • Build/deploy and configuration improvements: thanks to all the bug reports and suggestions, we've merged many improvements to configuring CloudFront inputs and other serverless.yml outputs, decoupling build step from the deploy step, etc.
  • Feature parity: except for the recently released Next.js 10 features, some more involved features (like revalidate on SSG), and a few miscellaneous bugs or quirks, the majority of Next.js 9.x features should be implemented and fairly stable and well-tested.

...and more. Thank you for all your support and contributions, and for helping us test and report bugs with the latest alpha versions!

That being said, we've also noticed these two biggest pain points:

  • Lambda@Edge and CloudFront are highly coupled with the core code of routing and rendering the correct pages. As an end user of this package, you may not notice it, but this actually makes it harder to support new platforms, such as Lambda, Cloudflare, GCP, Azure, etc. As a maintainer, it also makes it hard to separate testing the platform integration vs. testing the core code.
  • Infrastructure management has been difficult and sometimes has inconsistent results, as there is no first-class state management like a proper infrastructure-as-code (IaC) tool. The reason for this is that the Serverless Components we use (aws-cloudfront, domain, etc.) weren't well maintained and interfaced with the AWS SDK directly and do not manage state except for saving the Lambda function name, CloudFront distribution ID, etc (in the .serverless directory).

This brings us to the next set of challenges:

  • Decoupling and modularizing the runtime code itself so it's not tied Lambda@Edge. This will help us in separating concerns to the respective packages. Fortunately, we have Rollup.js or other bundlers which can largely help with this. I propose the following:
    • Core Next.js code: this is the core routing and rendering logic, all specific to Next.js rendering of SSR, SSG pages and doing non-dynamic, dynamic routing.
    • Optional request/response middleware: any additional runtime code you'd like to run before/after the core serverless code is run. For example, you could use this to do basic authentication, log additional metrics, etc. This doesn't really belong to the core routing code. We could provide a few essential first-party middleware, the community can contribute additional middleware to the package, another package, or use their own.
    • Bundler: bundles the core Next.js code together with any included middleware, including custom middleware.
    • Platform plugins: these plugins are responsible for building and deploying the code to a specific platform. For example, this can be Lambda@Edge, Lambda, Cloudflare, etc. Its responsibility is to take the bundled core code + middleware and further bundle that with lightweight platform compatibility layers that interface with the core. It can also perform any further optimizations as needed. For example, for Lambda@Edge, this will involve the CloudFront event.
      As part of this, we may also plan to reduce the Lambda@Edge handlers into a single origin request handler to simplify the architecture and even improve performance by reducing cold start + CloudFront + S3 origin + Lambda complexity.

In essence, everything except for the platform plugins should be platform-agnostic.

  • Properly decoupling build and deploy steps, and making it more configurable: much of this is already done, as you can just build only .serverless_nextjs outputs using this component, and actually deploy using your own IaC tools - although there is no first-party implementation of CDK yet. This brings us to the last point:

  • Proper infrastructure-as-code and state management. We've seen that our use of AWS SDK means we need to keep updating deployment code to support new features. There is also no proper state management. Fortunately, there are tools like CDK, Terraform, Pulumi etc. that have already already solved these issues, by storing state remotely (e.g in Terraform, you can store it in Terraform, S3, etc).

    • Explore the use of CDK / CDK for Terraform / Pulumi. We are leaning towards CDK and CDK for Terraform, since I am familiar with Terraform and it also seems to have the most providers and gives more flexibility. Also, a deployment has two phases: provisioning static infrastructure, like CloudFront, Lambda@Edge, and S3, and uploading/deploying new code and assets, so this lends itself well.
  • Serverless Components GA upgrade: with all the above in mind, we are still planning to upgrade to Serverless Components GA as part of this. The plan is for some of the above refactoring to make this much easier.

We hope to incorporate at least some of these into the next major release (v2), I am hoping sometime in Q1 2021. Please share any thoughts or feedback you may have. We could also definitely use some help on some of this (after or in parallel to modularization), especially on supporting new platforms other than Lambda@Edge, since it's mostly @danielcondemarin and me maintaining this package.

I will update this post as I get more feedback. Thank you for reading!

FYI: @danielcondemarin

TL;DR: for v2 release, we are planning to modularize and decouple the component from Lambda@Edge, make it more platform-agnostic and support more platform deployments, and improve pain points related to infrastructure management. In addition, we will plan to upgrade to Serverless Components GA. We would love feedback or comments to help us improve.

@dphang dphang pinned this issue Nov 7, 2020
@chancity
Copy link

Sounds like fun, I'd be happy to help!

@JordanLao
Copy link

JordanLao commented Nov 12, 2020

Hi,
How much work do you think it would take to support Lambda?
And do you plan to support Fastly?

@dphang
Copy link
Collaborator Author

dphang commented Nov 12, 2020

@chancity sure, that would be great, feel free to ping @danielcondemarin if you'd like to be added to the Slack to discuss. We'd definitely love some help

@JordanLao we do want to support Lambda next, though first as mentioned we want to:

  1. Simplify the handler and decouple the core routing code from any particular platform. Thereafter the build outputs look largely the same.
  2. We'd need to write deployment logic and additional layer to make it compatible with Lambda. I think we plan to support new platforms using CDK/CDK for Terraform since that is more robust than trying to manage infrastructure ourselves using the AWS SDK (as we are now).

(1) involves quite a bit of refactoring, so probably best to be done by a core contributor. If you would like to help with (2), let me know and we can add you to the Slack. Basically for (2) you could actually start on the deployment logic (setting up Lambda, uploading to S3, API Gateway, CloudFront for assets etc.) assuming that the build outputs look something similar to the existing .serverless_nextjs folder (with default-lambda, api-lambda, assets directories, though of course the handler will remove CloudFront specific logic).

As for Fastly, I don't believe they support JavaScript yet, unless something changed? See: https://www.fastly.com/blog/why-edge-compute-does-not-yet-support-javascript. They also don't use Node.js nor V8 isolates (like Cloudflare Workers) so it would even trickier, I imagine. I would say that it would be easier to add Cloudflare Workers support - as FAB project has already done so to some extent.

@chancity
Copy link

@danielcondemarin slack please :)

@danielcondemarin
Copy link
Contributor

@chancity If you DM me on https://twitter.com/dcondemarin I'll send you an invite 👍

@chancity
Copy link

@chancity If you DM me on https://twitter.com/dcondemarin I'll send you an invite 👍

DM'd!

This was referenced Dec 19, 2020
@kirkness kirkness mentioned this issue Jan 18, 2021
7 tasks
@iDVB
Copy link

iDVB commented Jan 21, 2021

@dphang I'm just coming back to Serverless Components since it was in beta. In the mean time been suing CDK and CFN SLS. Your mention above about using CDK for this project caught my eye. I would love to discuss more over slack or something. I'd like to get up to speed on this direction.

@garyburtonjisc
Copy link

Hi, are there plans to support Azure? I am potentially working on a project that would need Azure support so would definitely be willing to help in any way I can. Once the decoupling work is done is it then a matter of implementing Azure ports of the existing components?

@dphang
Copy link
Collaborator Author

dphang commented Feb 4, 2021

@garyburtonjisc yes the major hurdle is we need to first decouple Lambda/CloudFront stuff, and also I/others may not have enough expertise in Azure functions.

If you would like to help start on the Azure part (e.g create a plugin to help package/deploy to Azure) please let @danielcondemarin know, we can add you to the Slack.

@dphang
Copy link
Collaborator Author

dphang commented Feb 4, 2021

@iDVB yes I think there is a PR out for adding CDK that @kirkness was working on for CDK deployment. Will be reviewing it since he mentioned it is ready.

Basically, build and deploy is already decoupled, and we provide a way to deploy using serverless components via AWS SDK, but yeah you can use CDK/CDK for Terraform/your own script, you'd just need to know where to upload the build outputs of .serverless_nextjs folder, e.g: uploading to S3, uploading Lambda, set CloudFront behavior etc.

Feel free to check with @danielcondemarin for invite to the Slack

@dphang
Copy link
Collaborator Author

dphang commented Jun 22, 2021

I will close this for now since I think the future plans are quite clear: Currently work is being done to support Lambda/APIGW and help reduce complexity (trying to remove origin response handler, etc.), and after we can start looking at other platforms.

@dphang dphang closed this as completed Jun 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants