Skip to content

Instantly share code, notes, and snippets.

@Maxiviper117
Last active October 17, 2024 09:57
Show Gist options
  • Select an option

  • Save Maxiviper117/1499a35900e158346ca13bdb005b70fe to your computer and use it in GitHub Desktop.

Select an option

Save Maxiviper117/1499a35900e158346ca13bdb005b70fe to your computer and use it in GitHub Desktop.
Express V5 Subtle changes
import express, { Request, Response, NextFunction } from "express";
const app = express();
/**
* Middleware to parse URL-encoded data
* v5 Change: No need to set `extended` to `false` explicitly, it's now the default
*/
app.use(express.urlencoded()); // Default behavior parses simple key-value pairs in query strings
/**
* Custom error interface extending the built-in Error class
*/
interface CustomError extends Error {
status?: number;
}
/**
* Error handling middleware
* v5 Change: Promises are forwarded automatically to this error handler; no need to manually catch them in routes
*/
app.use((err: CustomError, req: Request, res: Response, next: NextFunction) => {
res.status(err.status || 500).send({ error: err.message });
});
/**
* Async function simulating data loading with a chance of failure
*/
function loadData(): Promise<{ data: string }> {
return new Promise((resolve, reject) => {
const doesFail = Math.random() > 0.5;
if (doesFail) {
const error: CustomError = new Error("Failed to load data");
error.status = 404;
reject(error);
} else {
resolve({ data: "Data successfully loaded" });
}
});
}
/**
* CHANGED: No need to use try/catch handle with `next` parameter to forward errors in v5.
* Errors are automatically forwarded to error middleware.
*/
app.get("/data", async (req: Request, res: Response) => {
const data = await loadData(); // Automatically throws error if promise rejects
res.status(200).send(data);
});
// Old v4 way:
/**
* Route handler for "/data" endpoint.
* In v4, errors were manually caught and forwarded using `next`.
* In v5, errors are automatically forwarded to the error handling middleware.
*/
// app.get("/data", async (req: Request, res: Response, next: NextFunction) => {
// try {
// const data = await loadData();
// res.status(200).send(data); // Correct use of res.status().send() in v5
// } catch (err) {
// next(err); // Error automatically forwarded
// }
// });
/**
* CHANGED: Route path matching using new syntax in v5.
* v5 Change: Using `+` to match one or more values in the path (e.g., /items/1/details or /items/1/2/details)
*/
app.get("/items/:id+/details", (req: Request, res: Response) => {
const ids = req.params.id.split("/"); // Handles multiple IDs (e.g., /items/1/2/details)
res.send(`Items with IDs: ${ids}`);
});
/**
* CHANGED: Route path matching using new syntax in v5.
* v5 Change: Using `(.*)` to match any characters in the path (e.g., /files/path/to/file)
*/
app.get("/files/:name(.*)", (req: Request, res: Response) => {
const fileName = req.params.name; // Handles file paths like /files/path/to/file
res.send(`Requested file: ${fileName}`);
});
/**
* Route using new method signatures in v5.
* v5 Change: res.send(status, body) is no longer supported; use res.status(status).send(body)
*
*/
app.get("/status", (req: Request, res: Response) => {
res.status(200).send("Status OK"); // res.send(200, "OK") no longer valid in v5
});
const port = 3000;
app.listen(port, () => {
console.log(`Server is running at http://localhost:${port}`);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment