Basic HTTP Server
This example demonstrates how to create a simple but complete HTTP server with Verb, including routing, middleware, and error handling.
Overview
This basic HTTP server example covers:
- Creating an HTTP server
- Setting up routes
- Using middleware
- Handling errors
- Serving static files
- Request/response handling
Complete Code
import { createServer, middleware, ServerProtocol } from "verb";
const app = createServer(ServerProtocol.HTTP);
// Built-in middleware
app.use(middleware.json());
app.use(middleware.cors());
app.use(middleware.staticFiles("public"));
// Logging middleware
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
next();
});
// Basic routes
app.get("/", (req, res) => {
res.json({
message: "Welcome to Verb HTTP Server!",
timestamp: new Date().toISOString(),
version: "1.0.0"
});
});
app.get("/health", (req, res) => {
res.json({
status: "healthy",
uptime: process.uptime(),
memory: process.memoryUsage()
});
});
// Route with parameters
app.get("/users/:id", (req, res) => {
const { id } = req.params;
res.json({
id,
name: `User ${id}`,
email: `user${id}@example.com`
});
});
// Route with query parameters
app.get("/search", (req, res) => {
const { q, page = 1, limit = 10 } = req.query;
if (!q) {
return res.status(400).json({
error: "Query parameter 'q' is required"
});
}
res.json({
query: q,
page: parseInt(page),
limit: parseInt(limit),
results: [`Result for "${q}"`, `Another result for "${q}"`]
});
});
// POST route with body
app.post("/users", (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({
error: "Name and email are required"
});
}
// Simulate creating user
const user = {
id: Date.now().toString(),
name,
email,
createdAt: new Date().toISOString()
};
res.status(201).json(user);
});
// PUT route
app.put("/users/:id", (req, res) => {
const { id } = req.params;
const { name, email } = req.body;
res.json({
id,
name,
email,
updatedAt: new Date().toISOString()
});
});
// DELETE route
app.delete("/users/:id", (req, res) => {
const { id } = req.params;
res.json({
message: `User ${id} deleted successfully`,
deletedAt: new Date().toISOString()
});
});
// Route demonstrating different response types
app.get("/examples/responses", (req, res) => {
const { type = "json" } = req.query;
switch (type) {
case "json":
res.json({ type: "json", data: "JSON response" });
break;
case "text":
res.text("Plain text response");
break;
case "html":
res.html("<h1>HTML Response</h1><p>This is HTML content</p>");
break;
case "redirect":
res.redirect("/");
break;
default:
res.status(400).json({ error: "Invalid type parameter" });
}
});
// Error handling route (for demonstration)
app.get("/error", (req, res) => {
throw new Error("This is a test error");
});
// Global error handler
app.use((error, req, res, next) => {
console.error("Error:", error.message);
res.status(500).json({
error: "Internal Server Error",
message: process.env.NODE_ENV === "development" ? error.message : "Something went wrong"
});
});
// 404 handler (should be last)
app.use((req, res) => {
res.status(404).json({
error: "Not Found",
message: `Route ${req.method} ${req.path} not found`
});
});
// Start server
const port = process.env.PORT || 3000;
const host = process.env.HOST || "localhost";
app.listen(port, host);
console.log(`🚀 Server running at http://${host}:${port}`);
console.log("Available endpoints:");
console.log(" GET /");
console.log(" GET /health");
console.log(" GET /users/:id");
console.log(" GET /search?q=query");
console.log(" POST /users");
console.log(" PUT /users/:id");
console.log(" DELETE /users/:id");
console.log(" GET /examples/responses?type=json|text|html|redirect");
console.log(" GET /error (demo error handling)");
Step-by-Step Breakdown
1. Server Creation
import { createServer, middleware, ServerProtocol } from "verb";
const app = createServer(ServerProtocol.HTTP);
Create a basic HTTP server using the default protocol (HTTP).
2. Middleware Setup
// Built-in middleware
app.use(middleware.json());
app.use(middleware.cors());
app.use(middleware.staticFiles("public"));
// Custom logging middleware
app.use((req, res, next) => {
console.log(`${new Date().toISOString()} - ${req.method} ${req.path}`);
next();
});
Add middleware for JSON parsing, CORS support, static file serving, and request logging.
3. Basic Routes
app.get("/", (req, res) => {
res.json({
message: "Welcome to Verb HTTP Server!",
timestamp: new Date().toISOString(),
version: "1.0.0"
});
});
Simple GET route returning JSON response.
4. Route Parameters
app.get("/users/:id", (req, res) => {
const { id } = req.params;
res.json({
id,
name: `User ${id}`,
email: `user${id}@example.com`
});
});
Route with URL parameters accessible via req.params
.
5. Query Parameters
app.get("/search", (req, res) => {
const { q, page = 1, limit = 10 } = req.query;
if (!q) {
return res.status(400).json({
error: "Query parameter 'q' is required"
});
}
res.json({
query: q,
page: parseInt(page),
limit: parseInt(limit),
results: [`Result for "${q}"`, `Another result for "${q}"`]
});
});
Route handling query parameters with validation.
6. POST with Body
app.post("/users", (req, res) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({
error: "Name and email are required"
});
}
const user = {
id: Date.now().toString(),
name,
email,
createdAt: new Date().toISOString()
};
res.status(201).json(user);
});
POST route with request body validation.
7. Error Handling
// Global error handler
app.use((error, req, res, next) => {
console.error("Error:", error.message);
res.status(500).json({
error: "Internal Server Error",
message: process.env.NODE_ENV === "development" ? error.message : "Something went wrong"
});
});
Global error handler for uncaught errors.
8. 404 Handler
// 404 handler (should be last)
app.use((req, res) => {
res.status(404).json({
error: "Not Found",
message: `Route ${req.method} ${req.path} not found`
});
});
Catch-all handler for unmatched routes.
Running the Example
Save the code to a file called
server.ts
Install dependencies:
bashbun install verb
Create public directory (for static files):
bashmkdir public echo "<h1>Static File</h1>" > public/index.html
Run the server:
bashbun server.ts
Test the endpoints:
bash# Basic route curl http://localhost:3000/ # Health check curl http://localhost:3000/health # Route with parameters curl http://localhost:3000/users/123 # Query parameters curl "http://localhost:3000/search?q=typescript&page=1&limit=5" # POST request curl -X POST http://localhost:3000/users \ -H "Content-Type: application/json" \ -d '{"name":"John Doe","email":"[email protected]"}' # Different response types curl "http://localhost:3000/examples/responses?type=text" curl "http://localhost:3000/examples/responses?type=html"
Expected Output
GET /
{
"message": "Welcome to Verb HTTP Server!",
"timestamp": "2025-01-01T12:00:00.000Z",
"version": "1.0.0"
}
GET /health
{
"status": "healthy",
"uptime": 42.5,
"memory": {
"rss": 25165824,
"heapTotal": 7684096,
"heapUsed": 4857136,
"external": 1089470,
"arrayBuffers": 18898
}
}
GET /users/123
{
"id": "123",
"name": "User 123",
"email": "[email protected]"
}
POST /users
{
"id": "1704110400000",
"name": "John Doe",
"email": "[email protected]",
"createdAt": "2025-01-01T12:00:00.000Z"
}
Key Features Demonstrated
- HTTP Methods: GET, POST, PUT, DELETE
- Route Parameters:
:id
parameter extraction - Query Parameters: URL query string parsing
- Request Body: JSON body parsing
- Status Codes: Proper HTTP status codes
- Middleware: Built-in and custom middleware
- Error Handling: Global error handling
- Static Files: Serving static content
- Response Types: JSON, text, HTML responses
- Validation: Input validation and error responses
Common Patterns
Response Helper
const sendSuccess = (res: Response, data: any) => {
res.json({ success: true, data });
};
const sendError = (res: Response, message: string, status = 400) => {
res.status(status).json({ success: false, error: message });
};
Async Route Handler
app.get("/async-example", async (req, res) => {
try {
const data = await someAsyncOperation();
res.json(data);
} catch (error) {
res.status(500).json({ error: error.message });
}
});
Route Validation
const validateUser = (req: Request, res: Response, next: NextFunction) => {
const { name, email } = req.body;
if (!name || !email) {
return res.status(400).json({
error: "Name and email are required"
});
}
if (!isValidEmail(email)) {
return res.status(400).json({
error: "Invalid email format"
});
}
next();
};
app.post("/users", validateUser, (req, res) => {
// User data is validated
});
Next Steps
- Fullstack Application - Complete fullstack app with React
- File Upload Guide - Handle file uploads
- Security Guide - Add authentication and security
- WebSocket Protocol - Real-time features
Troubleshooting
Port Already in Use
# Find process using the port
lsof -i :3000
# Kill the process
kill -9 <PID>
CORS Issues
Add CORS middleware:
app.use(middleware.cors({
origin: ["http://localhost:3000", "http://localhost:8080"],
credentials: true
}));
JSON Body Not Parsed
Ensure JSON middleware is added:
app.use(middleware.json());