Simple API Example

A complete example showing how to build a simple REST API with MoroJS. This example includes CRUD operations, validation, and proper error handling.

What You'll Build

This example demonstrates a user management API with the following features:

  • Basic CRUD operations (Create, Read)
  • Request validation with Zod schemas
  • Query parameter filtering and search
  • Error handling and HTTP status codes
  • In-memory data storage (easily replaceable)

API Endpoints

GET /Welcome message
GET /healthHealth check
GET /usersList all users (with filtering)
POST /usersCreate a new user
GET /users/:idGet user by ID

Complete Implementation

src/server.ts

typescript

1import { createApp, z } from '@morojs/moro';
2
3// Create the app
4const app = createApp();
5
6// Simple schemas for validation
7const UserSchema = z.object({
8  name: z.string().min(2).max(50),
9  email: z.string().email(),
10  age: z.number().min(18).optional()
11});
12
13// In-memory storage for demo
14const users: Array<{ id: number; name: string; email: string; age?: number }> = [
15  { id: 1, name: 'John Doe', email: 'john@example.com', age: 30 },
16  { id: 2, name: 'Jane Smith', email: 'jane@example.com', age: 25 }
17];
18
19let nextId = 3;
20
21// Routes
22
23// Welcome endpoint
24app.get('/', (req, res) => {
25  return {
26    message: 'Welcome to Simple Moro API!',
27    endpoints: [
28      'GET / - This welcome message',
29      'GET /health - Health check',
30      'GET /users - List users',
31      'POST /users - Create user',
32      'GET /users/:id - Get user by ID'
33    ]
34  };
35});
36
37// Health check
38app.get('/health', (req, res) => {
39  return { status: 'ok', timestamp: new Date().toISOString() };
40});
41
42// Get all users with optional filtering
43app.get('/users', (req, res) => {
44  const limit = parseInt(req.query.limit || '10');
45  const search = req.query.search;
46  
47  let filteredUsers = users;
48  
49  if (search) {
50    filteredUsers = users.filter(user => 
51      user.name.toLowerCase().includes(search.toLowerCase()) ||
52      user.email.toLowerCase().includes(search.toLowerCase())
53    );
54  }
55  
56  return {
57    users: filteredUsers.slice(0, limit),
58    total: filteredUsers.length,
59    filters: { search, limit }
60  };
61});
62
63// Create a new user
64app.post('/users')
65  .body(UserSchema)
66  .handler((req, res) => {
67    const newUser = {
68      id: nextId++,
69      ...req.body
70    };
71    
72    users.push(newUser);
73    
74    return {
75      success: true,
76      user: newUser
77    };
78  });
79
80// Get user by ID
81app.get('/users/:id', (req, res) => {
82  const userId = parseInt(req.params.id);
83  
84  if (isNaN(userId)) {
85    res.statusCode = 400;
86    return { error: 'Invalid user ID' };
87  }
88  
89  const user = users.find(u => u.id === userId);
90  
91  if (!user) {
92    res.statusCode = 404;
93    return { error: 'User not found' };
94  }
95  
96  return { user };
97});
98
99// Start the server
100app.listen(3001, () => {
101  console.log('Simple API server running on http://localhost:3001');
102  console.log('Try these endpoints:');
103  console.log('   GET  http://localhost:3001/');
104  console.log('   GET  http://localhost:3001/users');
105  console.log('   POST http://localhost:3001/users');
106  console.log('   GET  http://localhost:3001/users/1');
107});

Testing the API

Here are some example requests you can make to test the API:

Create a new user

bash

1curl -X POST http://localhost:3001/users \
2  -H "Content-Type: application/json" \
3  -d '{
4    "name": "John Doe",
5    "email": "john@example.com",
6    "age": 30
7  }'

Get all users

bash

1curl http://localhost:3001/users

Get a specific user

bash

1curl http://localhost:3001/users/1

Get users with filtering

bash

1curl "http://localhost:3001/users?search=john&limit=5"

Key Features Demonstrated

Type Safety

  • • Zod schemas for validation
  • • Automatic type inference
  • • Parameter type checking
  • • Response type safety

Error Handling

  • • Proper HTTP status codes
  • • Consistent error format
  • • Validation error messages
  • • Not found handling

Validation

  • • Request body validation
  • • Parameter validation
  • • Email format checking
  • • Business rule validation

Best Practices

  • • RESTful API design
  • • Consistent response format
  • • Proper HTTP methods
  • • Clear endpoint naming

Next Steps