AzuraJS Logo
AzuraJSFramework
v2.2 Beta

Examples

Real-world examples and code snippets

Examples 💡

Real-world examples to help you build with AzuraJS.

Complete REST API Example 🎯

TypeScript

src/index.ts
import { AzuraClient, applyDecorators } from "azurajs";
import {
  Controller,
  Get,
  Post,
  Put,
  Delete,
  Body,
  Param,
  Query,
  Res,
} from "azurajs/decorators";
import { HttpError } from "azurajs/http-error";
import { createLoggingMiddleware } from "azurajs/middleware";
import type { ResponseServer } from "azurajs";

// Types
interface Post {
  id: number;
  title: string;
  content: string;
  author: string;
  createdAt: Date;
}

interface CreatePostDto {
  title: string;
  content: string;
  author: string;
}

// In-memory database
const posts: Post[] = [
  {
    id: 1,
    title: "Hello AzuraJS",
    content: "Getting started with AzuraJS",
    author: "Alice",
    createdAt: new Date(),
  },
];

@Controller("/api/posts")
export class PostController {
  @Get()
  getAllPosts(
    @Query("limit") limit: string,
    @Query("offset") offset: string,
    @Res() res: ResponseServer
  ) {
    const limitNum = limit ? Number(limit) : 10;
    const offsetNum = offset ? Number(offset) : 0;
    
    const paginatedPosts = posts.slice(offsetNum, offsetNum + limitNum);
    
    res.json({
      posts: paginatedPosts,
      pagination: {
        limit: limitNum,
        offset: offsetNum,
        total: posts.length,
      },
    });
  }

  @Get("/:id")
  getPost(@Param("id") id: string, @Res() res: ResponseServer) {
    const post = posts.find((p) => p.id === Number(id));
    
    if (!post) {
      throw new HttpError(404, "Post not found");
    }
    
    res.json({ post });
  }

  @Post()
  createPost(@Body() data: CreatePostDto, @Res() res: ResponseServer) {
    if (!data.title || !data.content || !data.author) {
      throw new HttpError(400, "Missing required fields");
    }
    
    const post: Post = {
      id: Date.now(),
      title: data.title,
      content: data.content,
      author: data.author,
      createdAt: new Date(),
    };
    
    posts.push(post);
    
    res.status(201).json({ post });
  }

  @Put("/:id")
  updatePost(
    @Param("id") id: string,
    @Body() data: Partial<CreatePostDto>,
    @Res() res: ResponseServer
  ) {
    const post = posts.find((p) => p.id === Number(id));
    
    if (!post) {
      throw new HttpError(404, "Post not found");
    }
    
    if (data.title) post.title = data.title;
    if (data.content) post.content = data.content;
    if (data.author) post.author = data.author;
    
    res.json({ post });
  }

  @Delete("/:id")
  deletePost(@Param("id") id: string, @Res() res: ResponseServer) {
    const index = posts.findIndex((p) => p.id === Number(id));
    
    if (index === -1) {
      throw new HttpError(404, "Post not found");
    }
    
    posts.splice(index, 1);
    
    res.json({ message: "Post deleted successfully" });
  }

  @Get("/search")
  searchPosts(@Query("q") query: string, @Res() res: ResponseServer) {
    if (!query) {
      throw new HttpError(400, "Search query required");
    }
    
    const results = posts.filter(
      (p) =>
        p.title.toLowerCase().includes(query.toLowerCase()) ||
        p.content.toLowerCase().includes(query.toLowerCase())
    );
    
    res.json({ posts: results, query });
  }
}

// Start server
const app = new AzuraClient();
const logger = createLoggingMiddleware(app.getConfig());
app.use(logger);
applyDecorators(app, [PostController]);
await app.listen();

JavaScript

src/index.js
const { AzuraClient } = require("azurajs");
const { HttpError } = require("azurajs/http-error");
const { createLoggingMiddleware } = require("azurajs/middleware");

// In-memory database
const posts = [
  {
    id: 1,
    title: "Hello AzuraJS",
    content: "Getting started with AzuraJS",
    author: "Alice",
    createdAt: new Date(),
  },
];

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

// Get all posts with pagination
app.get("/api/posts", (req, res) => {
  const { limit = 10, offset = 0 } = req.query;
  const limitNum = Number(limit);
  const offsetNum = Number(offset);
  
  const paginatedPosts = posts.slice(offsetNum, offsetNum + limitNum);
  
  res.json({
    posts: paginatedPosts,
    pagination: {
      limit: limitNum,
      offset: offsetNum,
      total: posts.length,
    },
  });
});

// Get single post
app.get("/api/posts/:id", (req, res) => {
  const { id } = req.params;
  const post = posts.find((p) => p.id === Number(id));
  
  if (!post) {
    throw new HttpError(404, "Post not found");
  }
  
  res.json({ post });
});

// Create post
app.post("/api/posts", (req, res) => {
  const { title, content, author } = req.body;
  
  if (!title || !content || !author) {
    throw new HttpError(400, "Missing required fields");
  }
  
  const post = {
    id: Date.now(),
    title,
    content,
    author,
    createdAt: new Date(),
  };
  
  posts.push(post);
  res.status(201).json({ post });
});

// Update post
app.put("/api/posts/:id", (req, res) => {
  const { id } = req.params;
  const { title, content, author } = req.body;
  
  const post = posts.find((p) => p.id === Number(id));
  
  if (!post) {
    throw new HttpError(404, "Post not found");
  }
  
  if (title) post.title = title;
  if (content) post.content = content;
  if (author) post.author = author;
  
  res.json({ post });
});

// Delete post
app.delete("/api/posts/:id", (req, res) => {
  const { id } = req.params;
  const index = posts.findIndex((p) => p.id === Number(id));
  
  if (index === -1) {
    throw new HttpError(404, "Post not found");
  }
  
  posts.splice(index, 1);
  res.json({ message: "Post deleted successfully" });
});

// Search posts
app.get("/api/posts/search", (req, res) => {
  const { q } = req.query;
  
  if (!q) {
    throw new HttpError(400, "Search query required");
  }
  
  const results = posts.filter(
    (p) =>
      p.title.toLowerCase().includes(q.toLowerCase()) ||
      p.content.toLowerCase().includes(q.toLowerCase())
  );
  
  res.json({ posts: results, query: q });
});

// Start server
await app.listen();

Authentication Example 🔐

src/controllers/AuthController.ts
import {
  Controller,
  Post,
  Get,
  Body,
  Headers,
  Res,
  HttpError,
} from "azurajs";
import type { ResponseServer } from "azurajs";
import { sign, verify } from "jsonwebtoken";
import { hash, compare } from "bcrypt";

const JWT_SECRET = process.env.JWT_SECRET || "your-secret-key";

interface User {
  id: number;
  email: string;
  password: string;
  name: string;
}

const users: User[] = [];

@Controller("/api/auth")
export class AuthController {
  @Post("/register")
  async register(@Body() data: any, @Res() res: ResponseServer) {
    if (!data.email || !data.password || !data.name) {
      throw new HttpError(400, "Missing required fields");
    }
    
    // Check if user exists
    if (users.find((u) => u.email === data.email)) {
      throw new HttpError(409, "User already exists");
    }
    
    // Hash password
    const hashedPassword = await hash(data.password, 10);
    
    const user: User = {
      id: Date.now(),
      email: data.email,
      password: hashedPassword,
      name: data.name,
    };
    
    users.push(user);
    
    // Generate token
    const token = sign({ id: user.id, email: user.email }, JWT_SECRET, {
      expiresIn: "24h",
    });
    
    res.status(201).json({
      token,
      user: {
        id: user.id,
        email: user.email,
        name: user.name,
      },
    });
  }

  @Post("/login")
  async login(@Body() data: any, @Res() res: ResponseServer) {
    if (!data.email || !data.password) {
      throw new HttpError(400, "Email and password required");
    }
    
    const user = users.find((u) => u.email === data.email);
    
    if (!user) {
      throw new HttpError(401, "Invalid credentials");
    }
    
    const valid = await compare(data.password, user.password);
    
    if (!valid) {
      throw new HttpError(401, "Invalid credentials");
    }
    
    const token = sign({ id: user.id, email: user.email }, JWT_SECRET, {
      expiresIn: "24h",
    });
    
    res.json({
      token,
      user: {
        id: user.id,
        email: user.email,
        name: user.name,
      },
    });
  }

  @Get("/me")
  getProfile(
    @Headers("authorization") auth: string,
    @Res() res: ResponseServer
  ) {
    if (!auth) {
      throw new HttpError(401, "No token provided");
    }
    
    const token = auth.replace("Bearer ", "");
    
    try {
      const decoded = verify(token, JWT_SECRET) as { id: number; email: string };
      const user = users.find((u) => u.id === decoded.id);
      
      if (!user) {
        throw new HttpError(404, "User not found");
      }
      
      res.json({
        user: {
          id: user.id,
          email: user.email,
          name: user.name,
        },
      });
    } catch (error) {
      throw new HttpError(401, "Invalid token");
    }
  }
}

File Upload Example 📤

src/controllers/UploadController.ts
import { Controller, Post, Req, Res } from "azurajs/decorators";
import type { RequestServer, ResponseServer } from "azurajs";
import { writeFile, mkdir } from "fs/promises";
import { randomUUID } from "crypto";
import { join } from "path";

@Controller("/api/upload")
export class UploadController {
  @Post("/image")
  async uploadImage(@Req() req: RequestServer, @Res() res: ResponseServer) {
    const chunks: Buffer[] = [];
    
    req.on("data", (chunk) => {
      chunks.push(chunk);
    });
    
    await new Promise((resolve) => {
      req.on("end", resolve);
    });
    
    const buffer = Buffer.concat(chunks);
    const filename = `${randomUUID()}.jpg`;
    const uploadDir = join(process.cwd(), "uploads");
    
    await mkdir(uploadDir, { recursive: true });
    await writeFile(join(uploadDir, filename), buffer);
    
    res.status(201).json({
      filename,
      size: buffer.length,
      url: `/uploads/${filename}`,
    });
  }
}

WebSocket Example 🔌

src/index.ts
import { AzuraClient } from "azurajs";
import { WebSocketServer } from "ws";

const app = new AzuraClient();

// HTTP routes...

const server = await app.listen(3000);

// Add WebSocket server
const wss = new WebSocketServer({ server });

wss.on("connection", (ws) => {
  console.log("Client connected");
  
  ws.on("message", (data) => {
    console.log("Received:", data.toString());
    
    // Broadcast to all clients
    wss.clients.forEach((client) => {
      if (client.readyState === 1) {
        client.send(data);
      }
    });
  });
  
  ws.on("close", () => {
    console.log("Client disconnected");
  });
});

Database Integration Example 🗄️

src/services/DatabaseService.ts
import { Pool } from "pg";

const pool = new Pool({
  host: process.env.DB_HOST,
  port: 5432,
  database: process.env.DB_NAME,
  user: process.env.DB_USER,
  password: process.env.DB_PASSWORD,
});

export class UserService {
  async findAll() {
    const result = await pool.query("SELECT * FROM users");
    return result.rows;
  }
  
  async findById(id: number) {
    const result = await pool.query("SELECT * FROM users WHERE id = $1", [id]);
    return result.rows[0];
  }
  
  async create(data: { name: string; email: string }) {
    const result = await pool.query(
      "INSERT INTO users (name, email) VALUES ($1, $2) RETURNING *",
      [data.name, data.email]
    );
    return result.rows[0];
  }
  
  async update(id: number, data: Partial<{ name: string; email: string }>) {
    const fields = [];
    const values = [];
    let paramIndex = 1;
    
    if (data.name) {
      fields.push(`name = $${paramIndex++}`);
      values.push(data.name);
    }
    
    if (data.email) {
      fields.push(`email = $${paramIndex++}`);
      values.push(data.email);
    }
    
    values.push(id);
    
    const result = await pool.query(
      `UPDATE users SET ${fields.join(", ")} WHERE id = $${paramIndex} RETURNING *`,
      values
    );
    
    return result.rows[0];
  }
  
  async delete(id: number) {
    await pool.query("DELETE FROM users WHERE id = $1", [id]);
  }
}

Complete Production Example 🚀

Check the full example in the examples folder of the repository.

Next Steps 📖

On this page