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

Can the spec expand to handle "code-split" backends? #41

Open
NathanielHill opened this issue Nov 29, 2019 · 3 comments
Open

Can the spec expand to handle "code-split" backends? #41

NathanielHill opened this issue Nov 29, 2019 · 3 comments

Comments

@NathanielHill
Copy link

One of the greatest benefits of using Zeit's infrastructure is that is incredibly simple to have a "code-split" backend.

Meaning you don't have a monolithic server.js, but rather multiple entry points based on the request path.

Benefits are more fault-tolerance, easier scaling, etc. I only see this pattern growing going forward.

Are there any plans on handling this design pattern with fab.dev? The logic to split the backend from an arbitrary server.js is probably impossible...

But seems like it would be possible if the user was required to follow a structure similar to Now/Next.js. Would want to make optional behind a flag for sure.

Or perhaps fab.dev could simply leverage frameworks that already handle this like Next and not try and implement this itself. Would still need to update the spec to support it though.

Thoughts @geelen ?

@geelen
Copy link
Contributor

geelen commented Nov 29, 2019

Yeah I've had this question come up a few times, and I admit that the FAB design as-is doesn't map well to the backend-split thing, so it's something i've got in the back of my mind.

So, there are two problems. The first is that I want programmatic control of the routing layer, not a config file. Zeit's infra requires a routing layer in front of your apps to load the correct partial backend, but I don't want a "config export" to be part of a FAB deploy if we can avoid it. I talked briefly with @mjackson about this: potentially there's scope for a first-class routing format that's shared between all platforms, but I'm not pursuing that actively. But I would more than happily raise it for discussion (either in an issue, on a call, or in person).

The second problem is that I'm not actually convinced of this statement: "more fault-tolerance, easier scaling ... see this pattern growing going forward". I see Zeit's backend code-splitting as being very driven by the Now v2 infrastructure on AWS Lambda, where each route-server has no concurrency, and cold starts are a major issue. Is that approach still valuable if you're running on Cloudflare Workers' infrastructure with cold-starts 1-2 orders of magnitude smaller? And, what's the impact of coding your server against the Fetch api rather than NodeJS HTTP (in terms of bundle size), like FABs do. I don't think what Zeit have done with Now is bad in any way, I just can't see clearly how much of their approach is applicable in different execution environments.

Not to mention the impact of a platform like Google Cloud Run, where you get a full docker container that can run fab serve with concurrency up to 80, but scales up and down like a Lambda. No idea if it's performant/cost-effective for front-of-line web traffic, but I can definitely see it outperforming Lambda, purely due to the option of having a single server dealing with concurrent requests. In that case, I'd argue that you'd want the entire backend in a monolithic server to maximise reuse of your servers and smooth out load.

My gut feel is that the FAB spec will extend to handle multi-part FAB backends, but they'll be unified behind a single entry point. So routing can still be programmatic, but your execution environment allows your entry.js bundle to call a route-a-handler.js bundle. In some environments, all the bundles will live together and get loaded once, and in others, each piece will get a dedicated serverless container and call into each other.

Happy for you (or others) to expand on why you'd like such a feature—so far I haven't encountered an app that's simply unviable with a single server.js but is viable with a route-split one, so my thoughts are a bit hypothetical to form a good conclusion.

@NathanielHill
Copy link
Author

Yes, I agree with most everything you just wrote. Only thing I can see at the moment is large apps that can't fit within the 50ms/1MB limits of Cloudflare Workers.

I like your idea in the second to last paragraph.

I love this project idea, and see it as one of the top three ideas making web development more sane over the next few years:

  • Server-less (pretty much solved)
  • Build-less with tools like @pika/web and browser ESM support
  • Runtime-less with new frameworks like Svelte, lit-html, or pure Web Components
  • Lock-in-less with fab.dev 😄

@geelen
Copy link
Contributor

geelen commented Apr 16, 2020

Going to leave this discussion open, but am gearing up for a real v1 release now without any multi-entry-point support. I'm open to the idea, or potentially something like a "FAB of FABs" where each "entry point" gets rendered to its own FAB, then you produce something of a router FAB that sits in front, at the edge, and proxies to the other.

While that's a bit awkward, it does mean that we could experiment with building more complex production systems out of single-purpose, optimised runtimes, rather than have to extend the spec and, as a consequence, make every runtime more complex.

Let's see how FABs start getting used and we'll know a bit more.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants