Prior Art
Problem
No single existing paradigm delivers the combination of properties Blong requires: type-safe modular architecture, fast test feedback, transparent deployment flexibility (monolith ↔ microservices), and minimal developer overhead. Building on a single technology stack (e.g., pure REST or pure GraphQL) forces trade-offs that compound over time. Blong therefore selectively adopts the strongest ideas from each paradigm and combines them into a coherent whole, while explicitly rejecting the parts that introduce accidental complexity.
Solution
Blong blends the good parts of well-known paradigms:
- API-first approach
- Application server
- Composition over inheritance
- Convention over configuration
- Declarative programming
- Dependency injection
- Domain driven design
- Fast feedback loop
- Indirection
- Inversion of control
- Modular programming
- Observability
- Remote procedure call
- Scripting language
- Service oriented architecture
- Test driven development
Blong has similarities with approaches also described elsewhere:
- Uber: Introducing Domain-Oriented Microservice Architecture
- Redhat: Distributed transaction patterns
- Voxer Engineering: Back-pressure and Unbounded Concurrency in Node.js
- Microsoft: Data-tier applications (DAC)
Design: How Paradigms Map to Framework Features
The table below maps each paradigm cluster to a concrete framework feature, making the adoption decisions explicit rather than aspirational.
| Paradigm Cluster | Adopted As | Example in Codebase |
|---|---|---|
| Domain-Driven Design | Realms as bounded contexts | core/handler-test-poc/order/ — the order realm owns all order logic |
| Convention over configuration | Semantic triple naming + layer folders | orderOrderCreate.ts in orchestrator/order/; no registration step needed |
| Dependency injection + Inversion of control | Handler factory function receives {handler, lib, errors, config} | handler(({handler: {orderOrderCreate}}) => ...) — dependencies injected by the framework |
| Composition over inheritance | Handlers compose other handlers via the proxy | orderFlowExecute calls orderOrderCreate + orderOrderConfirm |
| RPC | JSON-RPC 2.0 as the external API protocol | POST /rpc/order/order/create maps to orderOrderCreate |
| TDD + fast feedback loop | Hot-reload + automatic test rerun on file save | Watch.ts triggers test re-run within the same process on handler change |
| Observability | $meta.checkpoint?.(name, data) + real-time log | core/blong-log — UDP transport → WS viewer |
| Modular programming + SOA | Suites compose realms; realms deploy independently | config: {microservice: {adapter: true, orchestrator: true}} |
| Scripting language | Minimal boilerplate; one file per handler | ~20-line handler files with no class boilerplate |
What Blong Deliberately Avoids
Not every paradigm was adopted. The following were considered and rejected:
- Class-based inheritance for handlers — inheritance hierarchies obscure dependencies and make hot-reload harder. Composition via the handler factory is used instead.
- GraphQL as the primary API protocol — schema stitching and resolver complexity outweigh the benefits for internal microservice communication. JSON-RPC 2.0 is simpler and maps directly to semantic triple naming.
- Event sourcing as default persistence — valuable for specific domains but too expensive as a default pattern. Adapters abstract persistence without mandating event sourcing.
- Decorator-based metadata (e.g., NestJS
@Controller) — decorators couple metadata to implementation. Blong uses file-system conventions and activation config instead.
Future Ideas
-
Adopted vs. rejected decision matrix — for each paradigm in the list above, add a one-line "adopted because / rejected because" entry to make the rationale explicit for new contributors, not just the reference link.
-
Framework comparison table — add a concise comparison with tRPC, NestJS, and Fastify that maps each framework's approach to the paradigm clusters above, making Blong's trade-offs visible to developers choosing between frameworks.
-
Living paradigm map — generate the paradigm-to-feature table automatically from code annotations (e.g.,
@paradigm('DDD')JSDoc tag on handler factories) so the map stays accurate as the framework evolves.