AzuraJS Logo
AzuraJSFramework
v2.2 Beta

JavaScript Usage

Using AzuraJS with plain JavaScript

JavaScript Usage ๐Ÿ“

AzuraJS works great with plain JavaScript! While the framework is TypeScript-first, you can use all features with JavaScript using the functional API.

Why JavaScript? ๐Ÿค”

  • Simplicity - No transpilation needed for simple projects
  • Familiar - Express-like API that JavaScript developers know
  • Flexible - Use decorators in TypeScript, functions in JavaScript
  • Progressive - Start with JS, migrate to TS when needed

Quick Start ๐Ÿš€

1. Install AzuraJS

npm install azurajs

2. Create Configuration

azura.config.js
const config = {
  environment: "development",
  server: {
    port: 3000,
    cluster: false,
  },
  logging: {
    enabled: true,
    showDetails: true,
  },
};

export default config;

3. Create Your Server

index.js
import { AzuraClient } from "azurajs";
import { createLoggingMiddleware } from "azurajs/middleware";

const app = new AzuraClient();
const logger = createLoggingMiddleware(app.getConfig());
app.use(logger);

app.get("/", (req, res) => {
  res.json({ message: "Hello from JavaScript!" });
});

await app.listen();

4. Run It

bun run index.js
# or
node index.js

Functional API ๐Ÿ”ง

Defining Routes

import { AzuraClient } from "azurajs";

const app = new AzuraClient();

// GET route
app.get("/users", (req, res) => {
  res.json({ users: [] });
});

// POST route
app.post("/users", (req, res) => {
  const body = req.body;
  res.status(201).json({ created: body });
});

// PUT route
app.put("/users/:id", (req, res) => {
  const { id } = req.params;
  res.json({ id, updated: true });
});

// DELETE route
app.delete("/users/:id", (req, res) => {
  const { id } = req.params;
  res.status(204).send();
});

Request Parameters

// Path parameters
app.get("/users/:id/posts/:postId", (req, res) => {
  const { id, postId } = req.params;
  res.json({ userId: id, postId });
});

// Query parameters
app.get("/search", (req, res) => {
  const { q, limit = 10, page = 1 } = req.query;
  res.json({ query: q, limit: Number(limit), page: Number(page) });
});

// Request body
app.post("/data", (req, res) => {
  const body = req.body;
  res.json({ received: body });
});

// Headers
app.get("/info", (req, res) => {
  const userAgent = req.headers["user-agent"];
  res.json({ userAgent });
});

Middleware in JavaScript ๐Ÿ”Œ

Basic Middleware

// Simple logging
app.use((req, res, next) => {
  console.log(`${req.method} ${req.url}`);
  next();
});

// Request timing
app.use((req, res, next) => {
  const start = Date.now();
  next();
  const duration = Date.now() - start;
  console.log(`Request took ${duration}ms`);
});

Authentication Middleware

const authMiddleware = (req, res, next) => {
  const token = req.headers.authorization;
  
  if (!token) {
    return res.status(401).json({ error: "No token" });
  }
  
  // Verify token
  req.user = { id: 1, name: "User" };
  next();
};

// Apply to specific routes
app.get("/protected", authMiddleware, (req, res) => {
  res.json({ user: req.user });
});

Configurable Middleware

function createRateLimit(limit, windowMs) {
  const requests = new Map();
  
  return (req, res, next) => {
    const ip = req.socket.remoteAddress;
    const now = Date.now();
    
    const userRequests = requests.get(ip) || [];
    const recentRequests = userRequests.filter(time => now - time < windowMs);
    
    if (recentRequests.length >= limit) {
      return res.status(429).json({ error: "Too many requests" });
    }
    
    recentRequests.push(now);
    requests.set(ip, recentRequests);
    next();
  };
}

// Use it
const rateLimit = createRateLimit(100, 60000); // 100 requests per minute
app.use(rateLimit);

Complete Example ๐ŸŽฏ

Here's a complete REST API in JavaScript:

server.js
import { AzuraClient } from "azurajs";
import { createLoggingMiddleware } from "azurajs/middleware";

const app = new AzuraClient();
const logger = createLoggingMiddleware(app.getConfig());
app.use(logger);

// In-memory database
const users = [
  { id: 1, name: "Alice", email: "[email protected]" },
  { id: 2, name: "Bob", email: "[email protected]" },
];

let nextId = 3;

// List all users
app.get("/api/users", (req, res) => {
  const { page = 1, limit = 10 } = req.query;
  const startIndex = (page - 1) * limit;
  const endIndex = startIndex + Number(limit);
  
  res.json({
    data: users.slice(startIndex, endIndex),
    pagination: {
      page: Number(page),
      limit: Number(limit),
      total: users.length,
    },
  });
});

// Get user by ID
app.get("/api/users/:id", (req, res) => {
  const { id } = req.params;
  const user = users.find(u => u.id === Number(id));
  
  if (!user) {
    return res.status(404).json({ error: "User not found" });
  }
  
  res.json({ data: user });
});

// Create user
app.post("/api/users", (req, res) => {
  const { name, email } = req.body;
  
  if (!name || !email) {
    return res.status(400).json({ error: "Name and email required" });
  }
  
  const user = {
    id: nextId++,
    name,
    email,
    createdAt: new Date().toISOString(),
  };
  
  users.push(user);
  res.status(201).json({ data: user });
});

// Update user
app.put("/api/users/:id", (req, res) => {
  const { id } = req.params;
  const { name, email } = req.body;
  
  const user = users.find(u => u.id === Number(id));
  
  if (!user) {
    return res.status(404).json({ error: "User not found" });
  }
  
  if (name) user.name = name;
  if (email) user.email = email;
  user.updatedAt = new Date().toISOString();
  
  res.json({ data: user });
});

// Delete user
app.delete("/api/users/:id", (req, res) => {
  const { id } = req.params;
  const index = users.findIndex(u => u.id === Number(id));
  
  if (index === -1) {
    return res.status(404).json({ error: "User not found" });
  }
  
  users.splice(index, 1);
  res.status(204).send();
});

// Health check
app.get("/health", (req, res) => {
  res.json({ status: "healthy", timestamp: new Date().toISOString() });
});

// Start server
await app.listen();
// Set cookie
app.get("/login", (req, res) => {
  res.cookie("session", "abc123", {
    httpOnly: true,
    maxAge: 3600000, // 1 hour
    secure: true,
  });
  res.json({ message: "Logged in" });
});

// Read cookie
app.get("/profile", (req, res) => {
  const session = req.cookies.session;
  if (!session) {
    return res.status(401).json({ error: "Not authenticated" });
  }
  res.json({ session });
});

// Clear cookie
app.get("/logout", (req, res) => {
  res.clearCookie("session");
  res.json({ message: "Logged out" });
});

Error Handling โš ๏ธ

// Custom error handler middleware
app.use((req, res, next) => {
  try {
    next();
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Internal server error" });
  }
});

// Route-level error handling
app.get("/risky", (req, res) => {
  try {
    // Risky operation
    throw new Error("Something went wrong");
  } catch (error) {
    res.status(500).json({ error: error.message });
  }
});

Migration to TypeScript ๐Ÿ”„

When you're ready to add type safety:

  1. Rename files - .js โ†’ .ts
  2. Add types - Import types from azurajs
  3. Optional decorators - Use decorators for better organization
import { AzuraClient } from "azurajs";
import type { RequestHandler } from "azurajs/types";

const authMiddleware: RequestHandler = async (req, res, next) => {
  // Your middleware logic
  await next();
};

Best Practices โœจ

Use const - Prefer const over let when possible

Destructure - Use destructuring for cleaner code: const { id } = req.params

Async/await - Use async/await instead of callbacks

Error handling - Always handle errors properly

Performance Tips โšก

// Avoid creating middleware in routes
// โŒ Bad
app.get("/data", (req, res, next) => {
  const logger = createLogger(); // Created on every request!
  next();
}, handler);

// โœ… Good
const logger = createLogger(); // Created once
app.use(logger);
app.get("/data", handler);

Next Steps ๐Ÿ“š

Resources ๐Ÿ”—

On this page