Playground Examples
Overview
The project includes a comprehensive playground with real examples demonstrating all features of RNode Server.
Getting Started
Setup Playground
bash
cd playground
pnpm install
pnpm run dev:mini # Start development serverVisit http://localhost:4599 to explore all examples.
Main Application
Playground Structure
playground/
├── src/
│ ├── index.ts # Main application entry point
│ └── routers/ # Router examples
│ ├── api.ts # Basic API endpoints
│ ├── auth_api.ts # Authentication system
│ ├── common.ts # Common middleware
│ ├── cors.ts # CORS configuration
│ ├── multipart.ts # File upload handling
│ ├── static.ts # Static file serving
│ ├── templates.ts # Template engine usage
│ └── users.ts # User management
├── public/ # Static files
├── templates/ # HTML templates
├── uploads/ # File upload directory
└── ssl/ # SSL certificatesMain Application Features
- HTTP & HTTPS servers with SSL configuration
- Router integration with multiple API endpoints
- File upload/download with wildcard subfolder support
- Static file serving with security options
- Middleware integration for logging and CORS
Router Examples
Basic API Router (api.ts)
typescript
// Basic API endpoints and CRUD operations
const apiRouter = Router();
apiRouter.get('/health', (req, res) => {
res.json({ status: 'ok', timestamp: new Date().toISOString() });
});
apiRouter.get('/info', (req, res) => {
res.json({
version: '1.0.0',
features: ['routing', 'middleware', 'templates', 'file-ops']
});
});
app.useRouter('/api', apiRouter);Authentication Router (auth_api.ts)
typescript
// Authentication system with sessions
const authRouter = Router();
authRouter.post('/login', (req, res) => {
const { username, password } = req.body;
if (validateCredentials(username, password)) {
const sessionId = generateSessionId();
res.setCookie('sessionId', sessionId, {
httpOnly: true,
secure: true,
sameSite: 'Strict',
maxAge: 24 * 60 * 60 // 24 hours
});
res.json({ success: true, message: 'Logged in successfully' });
} else {
res.status(401).json({ success: false, message: 'Invalid credentials' });
}
});
authRouter.post('/logout', (req, res) => {
res.removeCookie('sessionId');
res.json({ success: true, message: 'Logged out successfully' });
});
app.useRouter('/auth', authRouter);CORS Router (cors.ts)
typescript
// CORS configuration and preflight handling
const corsRouter = Router();
corsRouter.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization');
if (req.method === 'OPTIONS') {
res.json({ success: true, message: 'Preflight OK' });
return;
}
next();
});
corsRouter.get('/data', (req, res) => {
res.json({ message: 'CORS-enabled endpoint', data: [1, 2, 3] });
});
app.useRouter('/cors', corsRouter);File Upload Router (multipart.ts)
typescript
// File upload and multipart form handling
const multipartRouter = Router();
// Single file upload
app.upload('/upload', {
folder: './uploads',
maxFileSize: 10 * 1024 * 1024, // 10MB
allowedExtensions: ['.png', '.jpg', '.pdf', '.txt']
});
multipartRouter.post('/upload', (req, res) => {
if (req.hasFile('document')) {
const file = req.getFile('document');
res.json({
success: true,
file: {
name: file.filename,
size: file.size,
type: file.contentType
}
});
} else {
res.status(400).json({ error: 'No file uploaded' });
}
});
// Multiple file upload
app.upload('/upload-multiple', {
folder: './uploads',
maxFileSize: 50 * 1024 * 1024, // 50MB
allowedExtensions: ['.png', '.jpg', '.pdf', '.docx'],
multiple: true,
maxFiles: 10
});
multipartRouter.post('/upload-multiple', (req, res) => {
const files = req.getFiles();
const fileCount = req.getFileCount();
if (fileCount > 0) {
res.json({
success: true,
files: files.map(file => ({
name: file.filename,
size: file.size,
type: file.contentType
})),
count: fileCount
});
} else {
res.status(400).json({ error: 'No files uploaded' });
}
});
app.useRouter('/multipart', multipartRouter);Static Files Router (static.ts)
typescript
// Static file serving examples
const staticRouter = Router();
// Basic static files
app.static('./public');
// Multiple directories with different settings
app.static(['./images', './icons'], {
cache: true,
maxAge: 86400, // 24 hours
maxFileSize: 10 * 1024 * 1024, // 10MB
gzip: false, // Images are already compressed
brotli: false
});
// Admin area with restricted access
app.static('./admin', {
cache: true,
maxAge: 1800, // 30 minutes
maxFileSize: 5 * 1024 * 1024, // 5MB
etag: true,
lastModified: true,
gzip: true,
brotli: true,
allowHiddenFiles: false,
allowSystemFiles: false,
allowedExtensions: ['html', 'css', 'js'],
blockedPaths: ['.git', '.env', '.htaccess', 'thumbs.db']
});
staticRouter.get('/stats', (req, res) => {
const stats = app.getStaticStats();
res.json({ success: true, stats });
});
app.useRouter('/static', staticRouter);Templates Router (templates.ts)
typescript
// Template engine usage examples
const templatesRouter = Router();
// Initialize Tera templates
app.initTemplates('./templates/**/*.html', { autoescape: true });
templatesRouter.get('/welcome', (req, res) => {
const result = app.renderTemplate('welcome.html', {
title: 'Welcome to Playground',
user: { name: 'Visitor', email: 'visitor@example.com' },
items: ['Feature 1', 'Feature 2', 'Feature 3']
});
const parsed = JSON.parse(result);
if (parsed.success) {
res.html(parsed.content);
} else {
res.status(500).json({ error: parsed.error });
}
});
templatesRouter.get('/dashboard', (req, res) => {
const result = app.renderTemplate('dashboard.html', {
title: 'Dashboard',
stats: {
users: 42,
posts: 128,
views: 1024
}
});
const parsed = JSON.parse(result);
if (parsed.success) {
res.html(parsed.content);
} else {
res.status(500).json({ error: parsed.error });
}
});
app.useRouter('/templates', templatesRouter);Users Router (users.ts)
typescript
// User management and database operations
const usersRouter = Router();
// Middleware for users router
usersRouter.use((req, res, next) => {
console.log('👥 Users Router Middleware:', req.method, req.url);
req.setParam('routerName', 'users');
next();
});
// Create user
usersRouter.post('', (req, res) => {
console.log('=== POST /api/users ===');
console.log('Body:', req.body);
try {
let userData = req.body;
if (typeof req.body === 'string') {
try {
userData = JSON.parse(req.body);
} catch (e) {
userData = { name: req.body, email: '', age: null };
}
}
if (!userData.name || !userData.email) {
return res.json({
success: false,
message: 'Name and email are required'
});
}
res.json({
success: true,
message: 'User created successfully',
userId: Date.now(),
user: userData
});
} catch (error) {
res.json({
success: false,
message: `Error: ${error.message}`
});
}
});
// Get all users
usersRouter.get('', (req, res) => {
console.log('=== GET /api/users ===');
res.json({ users: [] });
});
// Get user by ID
usersRouter.get('/{id}', (req, res) => {
const { id } = req.params;
res.json({ userId: id, message: 'User details' });
});
app.useRouter('/api/users', usersRouter);Common Middleware
Logging Middleware
typescript
// Common middleware and utilities
app.use((req, res, next) => {
const start = Date.now();
console.log(`${req.method} ${req.url} - Started`);
// Add response listener
res.on('finish', () => {
const duration = Date.now() - start;
console.log(`${req.method} ${req.url} - ${res.statusCode} - ${duration}ms`);
});
next();
});Authentication Middleware
typescript
app.use('/api/protected', (req, res, next) => {
const sessionId = req.getCookie('sessionId');
if (!sessionId) {
return res.status(401).json({ error: 'Authentication required' });
}
// Validate session (simplified)
if (sessionId.length > 10) {
req.setParam('isAuthenticated', true);
req.setParam('userId', 'user123');
next();
} else {
res.status(401).json({ error: 'Invalid session' });
}
});SSL Configuration
Generate SSL Certificates
bash
cd playground
pnpm run ssl:generateSSL Configuration
typescript
const app = createApp({
ssl: {
certPath: './ssl/server.crt',
keyPath: './ssl/server.key'
}
});Available Endpoints
API Endpoints
GET /api/health- Health checkGET /api/info- Server informationPOST /api/users- Create userGET /api/users- Get all usersGET /api/users/{id}- Get user by ID
Authentication
POST /auth/login- User loginPOST /auth/logout- User logout
File Operations
POST /multipart/upload- Single file uploadPOST /multipart/upload-multiple- Multiple file upload
Templates
GET /templates/welcome- Welcome templateGET /templates/dashboard- Dashboard template
CORS
GET /cors/data- CORS-enabled endpoint
Static Files
GET /static/*- Static file servingGET /static/stats- Static file statistics
Testing Examples
Test File Upload
bash
# Test single file upload
curl -X POST -F "document=@test.txt" http://localhost:4599/multipart/upload
# Test multiple file upload
curl -X POST -F "documents=@file1.txt" -F "documents=@file2.txt" \
http://localhost:4599/multipart/upload-multipleTest API Endpoints
bash
# Create user
curl -X POST -H "Content-Type: application/json" \
-d '{"name":"John","email":"john@example.com"}' \
http://localhost:4599/api/users
# Get users
curl http://localhost:4599/api/users
# Health check
curl http://localhost:4599/api/healthTest Templates
bash
# Welcome template
curl http://localhost:4599/templates/welcome
# Dashboard template
curl http://localhost:4599/templates/dashboardNext Steps
- Middleware Examples - Middleware patterns
- File Operations - File handling examples
- Advanced Usage - Advanced patterns
- API Reference - Complete API documentation