Routes & Routing
Learn how Kempo Server's file-based routing system works.
How Routes Work
A route is a request to a directory that will be handled by a file. To define routes, create the directory structure to the route and create a file with the name of the method that this file will handle. For example GET.js will handle the GET requests, POST.js will handle the POST requests and so on. Use index.js to handle all request types.
The Javascript file must have a default export that is the function that will handle the request. It will be passed a request object and a response object.
For example this directory structure:
my/
├─ route/
│ ├─ GET.js
│ ├─ POST.js
├─ other/
│ ├─ route/
│ │ ├─ GET.js
Would be used to handle GET my/route/, POST my/route/ and GET my/other/route/
HTML Routes
Just like JS files, HTML files can be used to define a route. Use GET.html, POST.html, etc... to define files that will be served when that route is requested.
my/
├─ route/
│ ├─ GET.js
│ ├─ POST.js
├─ other/
│ ├─ route/
│ │ ├─ GET.js
│ ├─ POST.html
│ ├─ GET.html
index fallbacks
index.js or index.html will be used as a fallback for all routes if a method file is not defined. In the above examples we do not have any routes defined for DELETE, PUT PATCH, etc... so lets use an index.js and index.html to be a "catch-all" for all the methods we have not created handlers for.
my/
├─ route/
│ ├─ GET.js
│ ├─ POST.js
│ ├─ index.js
├─ other/
│ ├─ route/
│ │ ├─ GET.js
│ │ ├─ index.js
│ ├─ POST.html
│ ├─ GET.html
│ ├─ index.html
├─ index.html
Dynamic Routes
A dynamic route is a route with a "param" in its path. To define the dynamic parts of the route just wrap the directory name in square brackets. For example if you wanted to get a users profile, or perform CRUD operations on a user you might create the following directory structure.
api/
├─ user/
│ ├─ [id]/
│ │ ├─ [info]/
│ │ │ ├─ GET.js
│ │ │ ├─ DELETE.js
│ │ │ ├─ PUT.js
│ │ │ ├─ POST.js
│ │ ├─ GET.js
When a request is made to /api/user/123/info, the route file api/user/[id]/[info]/GET.js would be executed and receive a request object with request.params containing { id: "123", info: "info" }.
Route Examples
Simple API Route
// api/hello/GET.js
export default async function(request, response) {
const { name } = request.query;
const message = name ? `Hello ${name}!` : 'Hello World!';
response.json({ message });
}
Dynamic User Profile Route
// api/users/[id]/GET.js
export default async function(request, response) {
const { id } = request.params;
const { includeProfile } = request.query;
// Simulate database lookup
const user = {
id: id,
name: `User ${id}`,
email: `user${id}@example.com`
};
if (includeProfile === 'true') {
user.profile = {
bio: `Bio for user ${id}`,
joinDate: '2024-01-01'
};
}
response.json(user);
}
Nested Dynamic Routes
// api/users/[id]/posts/[postId]/GET.js
export default async function(request, response) {
const { id, postId } = request.params;
const post = {
id: postId,
userId: id,
title: `Post ${postId} by User ${id}`,
content: 'This is the post content...',
createdAt: '2024-01-01T00:00:00.000Z'
};
response.json(post);
}
HTML Route Example
<!-- pages/about/GET.html -->
<!DOCTYPE html>
<html>
<head>
<title>About Us</title>
</head>
<body>
<h1>About Our Company</h1>
<p>We are a company that does amazing things.</p>
</body>
</html>
Route File Structure Best Practices
Organize by Feature
api/
├─ auth/
│ ├─ login/
│ │ ├─ POST.js
│ ├─ logout/
│ │ ├─ POST.js
│ ├─ register/
│ │ ├─ POST.js
├─ users/
│ ├─ [id]/
│ │ ├─ GET.js
│ │ ├─ PUT.js
│ │ ├─ DELETE.js
│ ├─ GET.js
│ ├─ POST.js
├─ posts/
│ ├─ [id]/
│ │ ├─ GET.js
│ │ ├─ PUT.js
│ │ ├─ DELETE.js
│ ├─ GET.js
│ ├─ POST.js
Use Index Files for Fallbacks
Use index.js to handle methods not explicitly defined:
// api/users/index.js
export default async function(request, response) {
// Handle any method not explicitly defined
response.status(405).json({
error: 'Method not allowed',
allowed: ['GET', 'POST']
});
}
Static File Serving
Any file that doesn't match a route pattern will be served as a static file. This includes:
- HTML files (except route files)
- CSS files
- JavaScript files (except route files)
- Images
- Any other static assets
Example static file structure:
public/
├─ index.html # Served at /
├─ styles.css # Served at /styles.css
├─ script.js # Served at /script.js
├─ images/
│ ├─ logo.png # Served at /images/logo.png
├─ api/ # Routes directory
│ ├─ hello/GET.js # Route handler