Basic Routing
Alapa provides a straightforward and flexible routing system for handling HTTP requests. Its routing design is similar to Express, allowing developers to define routes for various HTTP methods easily.
Defining Routes
Routes are defined using the Router
class, which maps specific HTTP methods and URLs to handler functions. Below is an example of a basic route definition:
import { Router, Request, Response } from "alapa";
const indexRoute = new Router();
// GET Route
indexRoute.get("/", (req: Request, res: Response) => {
res.send("Welcome to my site!");
});
export default indexRoute;
After Defining index Route you can now connect to application routes as show bellow
import { Router } from 'alapa'
import indexRoute from './index'
const routes = new Router()
routes.use(indexRoute)
export default routes
Supported HTTP Methods
Alapa supports all common HTTP methods, such as:
GET
POST
PUT
PATCH
DELETE
OPTIONS
ALL
Each method is mapped using a corresponding function (router.get
, router.post
, etc.).
Example:
import { Router, Request, Response } from "alapa";
const router = new Router();
// POST Route
router.post("/submit", (req: Request, res: Response) => {
const { name, email } = req.body;
res.send(`Data received: Name: ${name}, Email: ${email}`);
});
// PUT Route
router.put("/update", (req: Request, res: Response) => {
const { id, data } = req.body;
res.send(`Updating record ${id} with data: ${JSON.stringify(data)}`);
});
// All Route
router.all("/login", (req: Request, res: Response) => {
const { user, password } = req.body;
res.send(`The method is ${req.method}`);
});
// DELETE Route
router.delete("/remove/:id", (req: Request, res: Response) => {
const { id } = req.params;
res.send(`Record ${id} has been deleted.`);
});
Route Parameters
Dynamic segments can be added to routes using the :
syntax. Parameters are accessible via req.params
.
Example:
import { Router, Request, Response } from "alapa";
const userRoutes = new Router();
userRoutes.get("/users/:id", (req: Request, res: Response) => {
const id = req.params.id;
res.send(`Fetching details for user with ID: ${id}`);
});
export default userRoutes;
Fetching details for user with ID: 1
Query Strings
You can handle query strings in routes using req.query
.
Example:
router.get("/search", (req: Request, res: Response) => {
const { keyword, page } = req.query;
res.send(`Search results for '${keyword}' on page ${page}`);
});
Search results for foo
on page 2
router.all
Route
The all
method is a special route handler that matches all HTTP methods (GET, POST, PUT, DELETE, etc.) for a specific route. This is useful when you want to handle multiple types of requests on the same route but with different behavior depending on the HTTP method being used.
How the all
Method Works:
- The
router.all("/login", ...)
route will match any HTTP method that targets the/login
path. - Inside the route handler,
req.method
contains the HTTP method used for that specific request (such as GET, POST, PUT, etc.). - This allows you to write a single route handler for multiple methods and handle them dynamically based on the value of
req.method
.
Example Breakdown:
router.all("/login", (req: Request, res: Response) => {
const { user, password } = req.body;
res.send(`The method is ${req.method}`);
});
- Request Handling: This route handler will fire for any HTTP method (GET, POST, PUT, DELETE, etc.) that matches
/login
. - Dynamic Response Based on Method: The
req.method
value is dynamically injected based on the method that was used to make the request. For example:- If the request is a
GET
,req.method
will be"GET"
. - If the request is a
POST
,req.method
will be"POST"
.
- If the request is a
- The response will simply echo the HTTP method being used in the request.
Use Case of req.method
:
- POST Request: If you send a
POST
request to/login
, the handler will process the login form (usingreq.body
to get the user and password) and return a message like:The method is POST
. - GET Request: If you send a
GET
request to/login
, it will still match the route, but nowreq.method
will return"GET"
, and you can decide to return a different message or handle it in a different way.
Example with Different Behavior:
router.all("/login", (req: Request, res: Response) => {
if (req.method === "POST") {
const { user, password } = req.body;
res.send(`Login submitted with user: ${user}`);
} else if (req.method === "GET") {
res.render("account/login");
} else {
res.send(`Unsupported method: ${req.method}`);
}
});
- If the method is
POST
, it will process the login details. - If the method is
GET
, it will renderviews/account/login.html
template. - For any other HTTP method (like PUT, DELETE), it will return a message stating the method is unsupported.
Why Use all
Route?
The all
route is useful when you want to capture all possible HTTP methods for a specific URL and handle them accordingly. However, in many cases, it might be more readable and maintainable to use method-specific routes (e.g., router.get()
, router.post()
, etc.) when you know you only need to handle one HTTP method at a time.
The all
method is more suitable for situations where the behavior needs to vary dynamically based on the method being used.
Default Route (404 Handling)
To handle undefined routes, you can define a fallback route:
appRouter.all("*", (req: Request, res: Response) => {
res.status(404).send("Page not found");
});
Grouping Routes
Organize your routes by grouping them using separate files or route prefixes.
Example:
const userRouter = new Router();
userRouter.get("/profile", (req: Request, res: Response) => {
res.send("User profile");
});
const appRouter = new Router();
appRouter.use("/users", userRouter); // This handles routes prefixed with "/users"
export default appRouter;
Now, all routes under userRouter
will be prefixed with /users
.
User profile
Summary
Alapa routing is highly intuitive, enabling developers to handle routes, parameters, query strings, and even custom route grouping with ease.