@soapjs/soap
v0.12.1
Published
Lightweight, clean architecture-based framework designed to streamline the development of modular and maintainable web applications
Maintainers
Readme
SoapJS
Enterprise-ready Clean Architecture framework for TypeScript
⚠️ Work in Progress - Currently in development towards v1.0.0. API is stable and won't change, only additions will be made.
SoapJS brings enterprise architecture patterns to TypeScript applications. Build scalable, maintainable systems with Clean Architecture, DDD, CQRS, and Event Sourcing - framework and database agnostic.
Why SoapJS?
- Clean Architecture - DDD, CQRS, Event Sourcing out of the box
- Framework Agnostic - Works with Express, NestJS, Fastify, and more
- Database Agnostic - MongoDB, PostgreSQL, MySQL, Redis support
- Type-Safe - Full TypeScript support with generics
- Real-Time Ready - WebSocket and event-driven patterns
- Plugin System - Security, metrics, monitoring plugins
- Enterprise Features - Security, audit logging, transaction management
Quick Start
npm install @soapjs/soapimport { Entity, ReadWriteRepository, UseCase, Result, Where } from '@soapjs/soap';
// Define your domain entity
interface User extends Entity {
readonly name: string;
readonly email: string;
readonly age: number;
}
// Create a use case
@Injectable()
class CreateUserUseCase implements UseCase<User> {
constructor(
@Inject('UserRepository')
private userRepo: ReadWriteRepository<User>
) {}
async execute(data: { name: string; email: string; age: number }): Promise<Result<User>> {
const user: User = {
id: generateId(),
name: data.name,
email: data.email,
age: data.age
};
return this.userRepo.add(user);
}
}
// Type-safe queries work with any database
const activeUsers = await userRepo.find(
Where.valueOf('status').isEq('active')
.and.valueOf('age').isGte(18)
);Documentation
Core Concepts
- CQRS Pattern - Command Query Responsibility Segregation
- Event Bus - Event-driven architecture and messaging
- Advanced Event Patterns - Event replay, versioning, saga orchestration
- Repository Pattern - Data access abstractions
- Query Builder - Type-safe database queries
- Transactions - Database transaction management
- Dependency Injection - Service container and DI
HTTP & Real-time
- HTTP adapters - Optional Zod, OpenAPI, tracing — wire in your app, not in soap-express
- HTTP Routing - Framework-agnostic routing system
- Socket Communication - Real-time communication patterns
- Socket Handlers - WebSocket handler patterns
- HTTP App Architecture - HTTP application structure
Plugins & Monitoring
- Security Plugin - Security middleware and protection
- Memory Monitoring Plugin - Memory usage tracking
- Cache - Caching strategies and patterns
Query Building
- Where Conditions - Complex query condition building
Perfect For
- Enterprise Applications - Complex business logic with multiple domains
- Microservices - Consistent architecture across services
- Real-Time Applications - WebSocket-based features and event-driven interactions
- Legacy Modernization - Gradual migration to Clean Architecture
What's included and what needs an adapter
SoapJS is deliberately split into two categories: things that work out of the box, and extension points that define the contract your adapter must fulfill.
Ready to use
| Component | Description |
|-----------|-------------|
| Result, Failure | Error handling without exceptions |
| Entity, ValueObject, UseCase | Domain building blocks |
| Where, RepositoryQuery | Type-safe query builder |
| ReadRepository, ReadWriteRepository | Repository base classes (wire up your data source) |
| Transaction, TransactionRunner | Transaction management |
| InMemoryCommandBus | Command dispatch — great for development and testing |
| InMemoryQueryBus | Query dispatch — great for development and testing |
| InMemoryEventStore | Event store — great for development and testing |
| EventProcessor, EventDispatcher | Event processing with retry, backoff, DLQ |
| BaseHttpApp, routing, plugins | Framework-agnostic HTTP layer |
| DecoratorRegistry, HttpContract, ApiDocFragment, Tracer / Span | Route/CQRS metadata registry + HTTP ports for adapters |
| SecurityPlugin, MetricsPlugin, MemoryMonitoringPlugin | Production-ready HTTP plugins |
| SocketServer, SocketClient | WebSocket communication |
| DIContainer, @Injectable, @Inject | Dependency injection |
Extension points (implement the interface, or extend the base class)
These provide the full contract and a skeletal implementation. Wire them to your infrastructure (Kafka, MongoDB, Redis, etc.) by implementing the interface or extending the base class.
| Component | Interface to implement | Base class to extend |
|-----------|----------------------|---------------------|
| Event Bus (Kafka, RabbitMQ, SQS…) | EventBus<M, H> | — |
| Event Store (MongoDB, PostgreSQL…) | EventStore | — |
| Aggregate Root | — | BaseAggregateRoot<T> |
| Saga | — | BaseSaga (implement executeCommand) |
| Saga Orchestrator | SagaOrchestrator | BaseSagaOrchestrator (implement executeStep) |
| Event Replay | EventReplayManager | BaseEventReplayManager |
| Event Versioning | EventVersionManager | BaseEventVersionManager |
| Event Correlation | EventCorrelationManager | BaseEventCorrelationManager |
| Snapshots | SnapshotManager | BaseSnapshotManager |
| HTTP Application | HttpApp<F> | BaseHttpApp<F> |
| Request contracts (Zod, TypeBox, …) | — | Use HttpContract + route apiDoc / middlewares.pre from your adapter |
| API documentation (OpenAPI, …) | HttpPlugin | e.g. @soapjs/soap-openapi DocumentationPlugin |
| Distributed tracing | Tracer, Span | e.g. @soapjs/soap-node-otel NoopTracer or OpenTelemetry |
| Cache | CacheManager | — |
| Database Session | DatabaseSession | — |
Note:
BaseEventCorrelationManager,BaseSnapshotManagerandBaseEventReplayManagerstore state in memory. For production use they need a persistentEventStoreandSnapshotStore— implement those interfaces against your database of choice.
HTTP adapter packages (separate repos)
| Package | Role |
|---------|------|
| @soapjs/soap-express | Express controllers, routing, bootstrap — no Zod/OpenAPI/OTel bundled |
| @soapjs/soap-contract-zod | bodyContract() → validation middleware + apiDoc |
| @soapjs/soap-openapi | OpenAPI 3 + Swagger UI plugin |
| @soapjs/soap-node-otel | TracingMiddleware + noop tracer implementing Tracer |
Wire them in your index.ts via bootstrap({ plugins, middleware: { pre } }).
Roadmap (v1.x)
- Framework adapters:
@soapjs/soap-express,@soapjs/soap-fastify - Database adapters:
@soapjs/soap-mongo,@soapjs/soap-postgres - Event bus adapters:
@soapjs/soap-rabbit,@soapjs/soap-kafka - CLI tools and project boilerplates
Example Usage
// HTTP Plugin System
import { HttpApp, SecurityPlugin, MetricsPlugin } from '@soapjs/soap';
const app = new SoapExpress();
app.usePlugin(new SecurityPlugin({
enableCSRF: true,
enableSecurityHeaders: true,
exposeEndpoints: true
}));
app.usePlugin(new MetricsPlugin({
exposeEndpoint: true,
metricsPath: '/metrics'
}));// Custom Repository
class UserRepository extends ReadWriteRepository<User, UserDocument> {
async findByEmail(email: string): Promise<Result<User | null>> {
return this.find(Where.valueOf('email').isEq(email));
}
}Community
- GitHub Discussions - Ask questions and share ideas
- YouTube - Video tutorials and demos
License
MIT License - see LICENSE for details.
Enterprise Support
Need enterprise support, consulting, or custom integrations?
- Enterprise Support - Priority support and SLAs
- Architecture Consulting - Clean Architecture implementation
- Migration Services - From legacy to Clean Architecture
- Training Programs - Team training and workshops
Contact: [email protected]
SoapJS - Enterprise-ready Clean Architecture framework for scalable, maintainable applications.
