Core Concepts
Understand the key concepts and architecture of Azura.JS Framework.
Server Architecture
Azura is built around a modular architecture that separates concerns and makes your code more maintainable:
- AzuraServer - The core HTTP server that handles requests and responses
- Router - Responsible for matching URLs to route handlers
- Controllers - Class-based handlers for organizing your API endpoints
- Plugins - Modular extensions that add functionality to the server
- Lifecycle Hooks - Allow you to execute logic at various stages of the request/response cycle
Request Flow
1. Client sends HTTP request
2. AzuraServer receives the request
3. Middleware and global plugins process the request
4. Router matches the URL to a handler
5. Controller method executes
6. Response is sent back to the client
Decorators
Azura makes extensive use of TypeScript decorators to provide a clean and intuitive API:
Controller Decorators
@Controller('/users')
class UserController {
// Controller methods
}
Route Decorators
@Controller('/users')
class UserController {
@Get('/')
getAllUsers() {
// Handle GET /users
}
@Post('/')
createUser() {
// Handle POST /users
}
@Get('/:id')
getUserById(@Param('id') id: string) {
// Handle GET /users/:id
}
}
Parameter Decorators
@Controller('/users')
class UserController {
@Post('/')
createUser(
@Body() userData: any,
@Headers('user-agent') userAgent: string,
@Query('role') role?: string
) {
// Access to parsed body, headers, and query parameters
}
}
Decorator Support
experimentalDecorators
and emitDecoratorMetadata
in your tsconfig.json
.Plugin System
Azura's plugin system allows you to extend the framework's functionality in a modular way:
import { AzuraServer, cors, rateLimit } from '@azura/framework';
const app = new AzuraServer();
// Register built-in plugins
app.registerPlugin(cors, {
origin: '*',
methods: ['GET', 'POST', 'PUT', 'DELETE'],
});
app.registerPlugin(rateLimit, {
limit: 100,
timeframe: 60000, // 1 minute
});
// Create and register a custom plugin
const myPlugin = {
name: 'my-plugin',
register: (app, options) => {
app.use((req, res, next) => {
console.log('Request to', req.url);
next();
});
return {
// Plugin API that other plugins can use
logMessage: (msg: string) => console.log('[MyPlugin]', msg)
};
}
};
app.registerPlugin(myPlugin);
Configuration
Azura uses a configuration system that supports multiple formats:
azura.config.ts
- TypeScript configurationazura.config.js
- JavaScript configurationazura.config.json
- JSON configurationazura.config.yaml
- YAML configuration
// azura.config.ts
import { AzuraConfig } from '@azura/framework';
const config: AzuraConfig = {
server: {
port: 8080,
cluster: true, // Enable cluster mode
ipHost: true, // Show IP addresses on startup
},
plugins: {
cors: {
enabled: true,
origin: '*',
},
compression: {
enabled: true,
level: 6,
},
rateLimit: {
enabled: true,
limit: 100,
timeframe: 60000, // 1 minute
},
},
};
export default config;
Azura automatically loads this configuration when you create a new server instance.
Database Adapters
Azura provides a unified interface for working with different databases through adapters:
import { JSONAdapter, MongoAdapter, PostgresAdapter } from '@azura/framework';
// Simple JSON file database
const jsonDB = new JSONAdapter('database.json');
await jsonDB.connect();
// MongoDB adapter
const mongoDB = new MongoAdapter('mongodb://localhost:27017', 'my-app');
await mongoDB.connect();
// PostgreSQL adapter
const pgDB = new PostgresAdapter({
host: 'localhost',
port: 5432,
user: 'postgres',
password: 'secret',
database: 'my-app'
});
await pgDB.connect();
// All adapters share the same API
const users = await mongoDB.find('users', { active: true });
await pgDB.insert('users', { name: 'John', email: 'john@example.com' });
await jsonDB.update('users', { id: '123' }, { lastLogin: new Date() });
Authentication
Azura provides built-in support for JWT-based authentication and API keys:
import { JwtManager, KeyManager, Auth, Public, Roles } from '@azura/framework';
// JWT authentication
const jwt = new JwtManager();
const token = jwt.sign({ userId: '123', role: 'admin' });
const payload = jwt.verify(token);
// API key management
const keyManager = new KeyManager(['key1', 'key2', 'key3']);
keyManager.check('key1'); // Passes
keyManager.check('invalid'); // Throws HttpError
// Using auth decorators
@Controller('/admin')
class AdminController {
@Get('/')
@Auth('admin') // Requires authentication with 'admin' role
getDashboard() {
return { /* dashboard data */ };
}
@Get('/public-stats')
@Public() // No authentication required
getPublicStats() {
return { /* public stats */ };
}
}
Middleware
Middleware functions can be used to process requests before they reach your route handlers:
import { AzuraServer } from '@azura/framework';
const app = new AzuraServer();
// Global middleware
app.use((req, res, next) => {
console.log(`${req.method} ${req.path}`);
next();
});
// Error handling middleware
app.use((req, res, next) => {
try {
next();
} catch (error) {
console.error('Error:', error);
res.status(500).json({ error: 'Internal server error' });
}
});
// Route-specific middleware
const authMiddleware = (req, res, next) => {
const token = req.headers.authorization;
if (!token) {
return res.status(401).json({ error: 'Unauthorized' });
}
next();
};
app.get('/protected', authMiddleware, (req, res) => {
res.json({ message: 'This is protected' });
});