Basic Usage - Novaxjs2 v8.3.0

New in v8.3.0:

Creating a Server

const Nova = require('novaxjs2');
const app = new Nova();

// Define routes
app.get('/', (req, res) => {
    return '<h1>Welcome to Novaxjs2 v8.3.0!</h1>';
});

// Start server
app.at(3000, () => {
    console.log('Server running on port 3000');
});

Route Parameters

// Dynamic route parameter
app.get('/user/:id', (req, res) => {
    const userId = req.params.id;
    return `User ID: ${userId}`;
});

// Query parameters
app.get('/search:', (req, res) => {
    const query = req.query.q;
    return `Search: ${query}`;
});

Request & Response

app.post('/api/data', (req, res) => {
    // Access request body
    const data = req.body;
    
    // Set response status
    res.status(201).json({
      success: true,
      data: data
    });
});

File Uploads

// Configure file uploads
app.setFileConfig({
  maxSize: 10, // MB
  allowedTypes: ['image/jpeg', 'image/png', 'application/pdf'],
  keepOriginalName: true,
  maxFiles: 3
});

// Handle file upload
app.post('/upload', (req, res) => {
  const files = req.files;
  const formData = req.body;
  
  return {
    message: 'Files uploaded successfully',
    files: Object.keys(files),
    formData: formData
  };
});

View Engine

// Set up Novax view engine
app.setViewEngine('novax', {
  viewsPath: './views',
  viewsType: 'html', // or 'js'
  helpers: {
    formatDate: (date) => new Date(date).toLocaleDateString()
  }
});

// Render a template
app.get('/profile', async (req, res) => {
  const userData = { name: 'John', joined: '2023-01-15' };
  const html = await app.render('profile', userData);
  return html;
});

Route Grouping

// Group routes under a common prefix
app.group('/api/v1', (api) => {
  api.get('/users', (req, res) => {
    return { users: ['John', 'Jane'] };
  });
  
  api.post('/users', (req, res) => {
    // Create new user
    return { success: true, user: req.body };
  });
  
  // Nested groups
  api.group('/admin', (admin) => {
    admin.get('/dashboard', (req, res) => {
      return { adminData: 'Secret info' };
    });
  });
});

Middleware

// Custom middleware
const authMiddleware = (req, res, next) => {
  const token = req.headers.authorization;
  if (!token) {
    res.status(401).json({ error: 'Unauthorized' });
    return;
  }
  next();
};

// Error handling middleware
app.useErrorMiddleware((err, req, res, next) => {
  console.error(err);
  res.status(500).json({ error: 'Something went wrong' });
});

// Apply middleware to specific routes
app.get('/protected', authMiddleware, (req, res) => {
  return { message: 'Protected content' };
});

Custom Error Handling

// Custom 404 handler
app.on(404, (err, req, res) => {
  return `<h1>Custom 404 Page</h1>
          <p>The route ${req.url} was not found</p>`;
});

// Custom 500 handler
app.on(500, (err, req, res) => {
  return `<h1>Server Error</h1>
          <p>${err.message}</p>`;
});

CORS Configuration

// Enable CORS
app.cors({
  origins: ['https://example.com', 'http://localhost:3000'],
  methods: 'GET, POST, PUT, DELETE, OPTIONS',
  headers: 'Content-Type, Authorization',
  credentials: true
});

Static File Serving

// Serve static files from 'public' directory
app.serveStatic('public');

// With custom options
app.init({
  staticPath: 'assets',
  minifier: true, // Enable content minification
  fileConfig: {
    maxSize: 5,
    allowedTypes: ['image/*'],
    maxFiles: 10
  }
});

Plugin System

// Using a plugin
const myPlugin = (context, options) => {
  context.addMethod('greet', function(name) {
    return `Hello, ${name}!`;
  });
  
  context.addRoute('get', '/greet/:name', (req, res) => {
    return this.greet(req.params.name);
  });
};

app.usePlugin(myPlugin, { prefix: '/api' });