Enterprise Application Example
A comprehensive enterprise-grade application built with MoroJS. Features modular architecture, authentication, database integration, and production-ready patterns.
Architecture Overview
This enterprise example demonstrates a real-world application with multiple modules, comprehensive testing, and production-ready configuration.
Project Structure (Functional Architecture)
typescript
1enterprise-app/
2├── src/
3│ ├── modules/
4│ │ ├── users/
5│ │ │ ├── index.ts # Module definition
6│ │ │ ├── routes.ts # Route handlers
7│ │ │ ├── sockets.ts # WebSocket handlers
8│ │ │ ├── actions.ts # Business logic
9│ │ │ └── types.ts # Type definitions
10│ │ ├── orders/
11│ │ │ ├── index.ts
12│ │ │ ├── routes.ts
13│ │ │ ├── actions.ts
14│ │ │ └── types.ts
15│ │ ├── todos/
16│ │ │ ├── index.ts
17│ │ │ ├── routes.ts
18│ │ │ ├── actions.ts
19│ │ │ └── types.ts
20│ │ └── health/
21│ │ └── index.ts
22│ └── server.ts # Main application
23├── package.json
24├── tsconfig.json
25└── README.md
26
27// Key Features Demonstrated:
28✅ Functional modular architecture
29✅ Event-driven communication
30✅ In-memory data storage (easily replaceable)
31✅ Comprehensive validation with Zod
32✅ WebSocket support per module
33✅ Versioned API endpoints (/api/v1.0.0/)
34✅ Middleware system
35✅ Type-safe request handling
36✅ Clean separation of concerns
37✅ Easy module loading/unloading
38✅ Graceful shutdown handling
39✅ Development-friendly logging
Enterprise Features
- • Multi-tenant architecture
- • Role-based access control
- • Audit logging
- • API versioning
Security
- • JWT authentication
- • Rate limiting
- • Input validation
- • CORS protection
Data Layer
- • PostgreSQL with Prisma
- • Redis caching
- • Database migrations
- • Connection pooling
Application Setup
Main Application Configuration (Functional Architecture)
typescript
1// src/server.ts - Enterprise Application with Functional Modules
2import { createApp } from '@morojs/moro';
3import UsersModule from './modules/users';
4import OrdersModule from './modules/orders';
5import TodosModule from './modules/todos';
6import HealthModule from './modules/health';
7
8async function createEnterpriseApp() {
9 // Use the functional createApp approach
10 const app = createApp({
11 cors: true,
12 compression: true,
13 helmet: true
14 });
15
16 // Simulated database (in real app, use MySQLAdapter)
17 const mockDatabase = {
18 users: [
19 { id: 1, name: 'John Doe', email: 'john@example.com', role: 'admin' },
20 { id: 2, name: 'Jane Smith', email: 'jane@example.com', role: 'user' }
21 ],
22 orders: [
23 { id: 1, userId: 1, product: 'Laptop', amount: 999.99, status: 'completed' },
24 { id: 2, userId: 2, product: 'Mouse', amount: 29.99, status: 'pending' }
25 ],
26 todos: [
27 { id: 1, title: 'Learn MoroJS', description: 'Explore the functional module architecture', completed: false, priority: 'high' }
28 ]
29 };
30
31 // Register database
32 app.database(mockDatabase);
33
34 // Add enterprise middleware
35 app.use((req: any, res: any, next: () => void) => {
36 console.log(`[${new Date().toISOString()}] ${req.method} ${req.path}`);
37 next();
38 });
39
40 // Load enterprise modules using the functional module system
41 await app.loadModule(HealthModule);
42 await app.loadModule(UsersModule);
43 await app.loadModule(OrdersModule);
44 await app.loadModule(TodosModule);
45
46 // Root endpoint
47 app.get('/', (req, res) => {
48 return {
49 message: 'Enterprise API with Functional Modules',
50 timestamp: new Date().toISOString(),
51 modules: ['health', 'users', 'orders', 'todos'],
52 architecture: 'functional-event-driven'
53 };
54 });
55
56 // Health check endpoint
57 app.get('/health', (req, res) => {
58 return {
59 status: 'ok',
60 timestamp: new Date().toISOString(),
61 uptime: process.uptime(),
62 architecture: 'Functional Modules Active'
63 };
64 });
65
66 return app;
67}
68
69async function bootstrap() {
70 try {
71 const app = await createEnterpriseApp();
72 const port = parseInt(process.env.PORT || '3002');
73
74 app.listen(port, () => {
75 console.log('🏢 Enterprise Application Started');
76 console.log(`HTTP API: http://localhost:${port}`);
77 console.log(`WebSocket: ws://localhost:${port}`);
78 console.log('Available APIs:');
79 console.log(` Root: http://localhost:${port}/`);
80 console.log(` Health: http://localhost:${port}/health`);
81 console.log(` Users: http://localhost:${port}/api/v1.0.0/users/`);
82 console.log(` Orders: http://localhost:${port}/api/v1.0.0/orders/`);
83 console.log(` Todos: http://localhost:${port}/api/v1.0.0/todos/`);
84 });
85
86 // Graceful shutdown
87 process.on('SIGTERM', () => {
88 console.log('🏢 Enterprise app shutting down gracefully...');
89 process.exit(0);
90 });
91
92 } catch (error) {
93 console.error('❌ Failed to start enterprise application:', error);
94 process.exit(1);
95 }
96}
97
98bootstrap();
Enterprise Module Example
Functional Users Module Implementation
typescript
1// modules/users/index.ts - Functional Module Architecture
2import { defineModule } from '@morojs/moro';
3import routes from './routes';
4import sockets from './sockets';
5import * as actions from './actions';
6import * as types from './types';
7
8export default defineModule({
9 name: 'users',
10 version: '1.0.0',
11 prefix: '/api/v1.0.0/users',
12
13 // Register routes
14 routes,
15
16 // Register WebSocket handlers
17 sockets,
18
19 // Export module actions and types
20 actions,
21 types,
22
23 // Module lifecycle hooks
24 onLoad: async (app) => {
25 console.log('👥 Users module loaded');
26 // Initialize any module-specific services here
27 },
28
29 onUnload: async (app) => {
30 console.log('👥 Users module unloaded');
31 }
32});
33
34// modules/users/routes.ts - Route definitions
35import { z, validate } from '@morojs/moro';
36import * as actions from './actions';
37
38export default function registerRoutes(app: any) {
39 // GET /api/v1.0.0/users/ - List all users
40 app.get('/', (req: any, res: any) => {
41 const users = actions.getAllUsers(req.database);
42 return {
43 success: true,
44 data: users,
45 total: users.length
46 };
47 });
48
49 // GET /api/v1.0.0/users/:id - Get user by ID
50 app.get('/:id',
51 validate({
52 params: z.object({
53 id: z.coerce.number()
54 })
55 }, (req: any, res: any) => {
56 const user = actions.getUserById(req.database, req.params.id);
57 if (!user) {
58 res.status(404);
59 return { error: 'User not found' };
60 }
61 return { success: true, data: user };
62 })
63 );
64
65 // POST /api/v1.0.0/users/ - Create new user
66 app.post('/',
67 validate({
68 body: z.object({
69 name: z.string().min(2).max(50),
70 email: z.string().email(),
71 role: z.enum(['admin', 'user']).default('user')
72 })
73 }, (req: any, res: any) => {
74 try {
75 const newUser = actions.createUser(req.database, req.body);
76 return {
77 success: true,
78 data: newUser,
79 message: 'User created successfully'
80 };
81 } catch (error: any) {
82 res.status(400);
83 return { error: error.message };
84 }
85 })
86 );
87
88 // PUT /api/v1.0.0/users/:id - Update user
89 app.put('/:id',
90 validate({
91 params: z.object({
92 id: z.coerce.number()
93 }),
94 body: z.object({
95 name: z.string().min(2).max(50).optional(),
96 email: z.string().email().optional(),
97 role: z.enum(['admin', 'user']).optional()
98 })
99 }, (req: any, res: any) => {
100 try {
101 const updatedUser = actions.updateUser(req.database, req.params.id, req.body);
102 if (!updatedUser) {
103 res.status(404);
104 return { error: 'User not found' };
105 }
106 return {
107 success: true,
108 data: updatedUser,
109 message: 'User updated successfully'
110 };
111 } catch (error: any) {
112 res.status(400);
113 return { error: error.message };
114 }
115 })
116 );
117}
118
119// modules/users/actions.ts - Business logic
120export function getAllUsers(database: any) {
121 return database.users || [];
122}
123
124export function getUserById(database: any, id: number) {
125 return database.users?.find((user: any) => user.id === id);
126}
127
128export function createUser(database: any, userData: any) {
129 // Check if email already exists
130 const existingUser = database.users?.find((u: any) => u.email === userData.email);
131 if (existingUser) {
132 throw new Error('User with this email already exists');
133 }
134
135 const newUser = {
136 id: Math.max(...database.users.map((u: any) => u.id), 0) + 1,
137 ...userData,
138 createdAt: new Date().toISOString(),
139 updatedAt: new Date().toISOString()
140 };
141
142 database.users.push(newUser);
143 return newUser;
144}
145
146export function updateUser(database: any, id: number, updateData: any) {
147 const userIndex = database.users?.findIndex((u: any) => u.id === id);
148 if (userIndex === -1) {
149 return null;
150 }
151
152 database.users[userIndex] = {
153 ...database.users[userIndex],
154 ...updateData,
155 updatedAt: new Date().toISOString()
156 };
157
158 return database.users[userIndex];
159}
Run the Example
Getting Started
typescript
1# Clone the repository
2git clone https://github.com/Moro-JS/examples.git
3cd examples/enterprise-app
4
5# Install dependencies
6npm install
7
8# Start development server (no database setup required)
9npm run dev
10
11# The application will be available at:
12# - API: http://localhost:3002
13# - Health Check: http://localhost:3002/health
14# - Users API: http://localhost:3002/api/v1.0.0/users/
15# - Orders API: http://localhost:3002/api/v1.0.0/orders/
16# - Todos API: http://localhost:3002/api/v1.0.0/todos/
17
18# Available scripts:
19npm run dev # Start development server
20npm run build # Build for production
21npm run start # Start production server
22
23# Note: This example uses functional modules with in-memory storage
24# No database setup required for basic functionality
25# Real enterprise apps would use database adapters (MySQL, PostgreSQL, etc.)
What You'll Learn
- • Enterprise-grade application architecture
- • Module-based code organization
- • Authentication and authorization patterns
- • Database design and optimization
- • Event-driven communication
- • Comprehensive testing strategies
- • Production deployment patterns
Key API Endpoints
Example API Usage
typescript
1# Application Root
2GET /
3# Returns: Application info and available modules
4
5# Health Check
6GET /health
7# Returns: Application health status and uptime
8
9# User Management (Functional Module)
10GET /api/v1.0.0/users/
11# Returns: List of all users
12
13GET /api/v1.0.0/users/1
14# Returns: User details by ID
15
16POST /api/v1.0.0/users/
17{
18 "name": "John Doe",
19 "email": "john@company.com",
20 "role": "admin"
21}
22
23PUT /api/v1.0.0/users/1
24{
25 "name": "Jane Doe",
26 "role": "user"
27}
28
29# Order Management (Functional Module)
30GET /api/v1.0.0/orders/
31# Returns: List of all orders
32
33GET /api/v1.0.0/orders/1
34# Returns: Order details by ID
35
36POST /api/v1.0.0/orders/
37{
38 "userId": 1,
39 "product": "Laptop",
40 "amount": 999.99,
41 "status": "pending"
42}
43
44# Todo Management (Functional Module)
45GET /api/v1.0.0/todos/
46# Returns: List of all todos
47
48POST /api/v1.0.0/todos/
49{
50 "title": "Learn MoroJS",
51 "description": "Explore functional modules",
52 "priority": "high"
53}
54
55# WebSocket Endpoints (per module)
56ws://localhost:3002/users # User-related events
57ws://localhost:3002/orders # Order-related events
58ws://localhost:3002/todos # Todo-related events