Building a Micro‑Backend with Midway: Split Monorepo Apps into Independent Services
This article explores the concept of a “micro‑backend” by adapting micro‑frontend principles to server‑side applications, detailing how to use IoC, monorepo management with Lerna, and Midway’s configurable scanning to split a large Node.js codebase into independent, maintainable domain modules without changing developer workflows.
Background
Microservice concepts have long existed, and micro‑frontend practices have been applied for some time. Micro‑frontend emerged from evolving front‑end architectures combined with backend microservice ideas to solve integration of different front‑end frameworks or versions.
Micro‑frontend is a browser‑side architecture similar to micro‑services, turning a monolithic web application into multiple small front‑end applications that can run, develop, and deploy independently.
Discussions reveal that micro‑frontend currently addresses legacy system migration more than new unified systems, where developers often rebuild from scratch.
The question arises: can the backend be micro as well? While micro‑services solve language‑level interoperability, large monolithic systems become increasingly complex.
In Alibaba‑like environments, many Node.js back‑ends serve admin and front‑end systems. Splitting the front‑end is easy, but turning the backend into micro‑services or FaaS introduces risks, mainly personnel cost and resistance to change.
We are not trying to force a service‑oriented architecture on traditional HTTP applications; routing and mature development environments make such a shift difficult.
We experimented with IoC in Midway, using decorators and injection to replace traditional instantiation and calls.
However, this does not shrink the application; the logic remains.
Traditional distributed calls split a system into many services but sacrifice maintainability and debugging without mature tooling.
Is there a way to split applications conveniently without affecting debugging, resource evaluation, or maintainability?
The answer may be yes.
Key challenges include:
Local development impact – cannot disrupt developers.
Deployment cost – minimize consumption.
Simplicity – easy to understand and maintain the split.
Future extensibility – migrate to micro‑services or FaaS.
We must address these one by one.
How to Split
At jsconf 2019 we proposed a function‑oriented split: separating the router layer (Controller) and vertically splitting business logic (Service).
This approach divides the app into Controller + Service, with business domains also vertically split. The original controller and service directories illustrate this idea.
Second question: how does code organization and development mode change after splitting?
Changes in Development Approach
Developers resist changes that increase cost without benefit. After code separation, we can manage packages via git sub‑repositories or tools like Lerna, but the development experience must stay familiar.
Framework loading support is required.
We demonstrate with a Midway project using Lerna monorepo to simulate splitting.
Simplified directory structure:
The main package is the primary app, while api, book, and video are domain modules providing respective capabilities.
Sub‑packages share the same layout as the original large app, containing the same domain‑abstracted files.
However, they won’t run out‑of‑the‑box; the framework needs slight adjustments.
Midway’s IoC scans directories to preload instances, but it cannot see the new sub‑package paths. Fortunately, the IoC container supports custom scan paths, so we simply add the sub‑package locations.
In a monorepo, sub‑packages are regular npm packages; we define a configuration.ts file, for example:
Now we only need to add the resolved sub‑package paths to the IoC scan configuration. We also add a dependency on the api package to expose RESTful services.
Thus both main and api can be developed and run independently while preserving the original development workflow.
Usage is via standard npm package imports, standard import syntax and class definitions, without extra semantics.
This is the “micro‑backend” model.
Deployment Model
Since the main package changes little, publishing only the main package suffices, which fits well for CRM back‑ends with many route combinations.
Thanks to the IoC system, we can extend capabilities to other scenarios. At the end of 2019 we opened the Midway‑faas codebase, enabling migration of Midway services to Midway‑faas modules.
This feature preview indicates that future Midway versions will support such extensible models, allowing developers to split applications, build vertical domain modules, and migrate from Midway to Midway‑faas.
Technology never stops; everything is possible with Midway.
Node Underground
No language is immortal—Node.js isn’t either—but thoughtful reflection is priceless. This underground community for Node.js enthusiasts was started by Taobao’s Front‑End Team (FED) to share our original insights and viewpoints from working with Node.js. Follow us. BTW, we’re hiring.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
