Ever wrote code like this? Stop it.
// 🚨 this is messy
const router = express.Router()
router.get("/posts", async (req, res) => {
res.json([])
})
export default router
One of the great features that come with modern frontend frameworks like Next.js is a /pages
directory where all your app's routes live in.
Luckily, we can achieve the same DX in our Express backend codebases too without writing our own ugly express.Router()
s but with the express-file-routing
package.
// ✅ this is enjoyable
export const get = async (req, res) => {
res.json([])
}
As you can see, it's a super clean approach and quite beneficial for code style and maintainability to split your Express route handlers into separate files.
Just by taking a look at a project's file structure, one can intuitively see what endpoints our API is about to provide.
├── app.ts
├── routes
└── posts
├── index.ts
└── [id].ts
└── package.json
-
/routes/posts/index.ts
→ /posts -
/routes/posts/[id].ts
→ /posts/:id
How to use Express file routing
This is quite of a straightforward process. Even though this post is more of an intro rather than a tutorial on how to use this express-file-routing
, here's a quick start.
All you need to do is to install express-file-routing
from npm.
npm install express-file-routing
In your main entry file, create an Express app instance and attach the file router.
// app.ts
import express from "express"
import { router } from "express-file-routing"
const app = express()
app.use("/", router()) // this is the magic
app.listen(4000)
You're already done!
Enqueuing new routes from now on is as easy as creating a file in /routes
and exporting your HTTP method handlers.
// /routes/posts.ts
export const get = async (req, res) => {
res.json([])
}
export const post = async (req, res) => {
await db.post.create()
res.status(201)
}
Even middlewares are supported by exporting an array of request handlers instead of a single one.
export const post = [
rateLimit(), userAuth(),
async (req, res) => {
res.status(201).json({})
}
]
For detailed docs check out https://github.com/matthiaaas/express-file-routing.
Thanks for reading and stop using express.Router()
ever again.
Top comments (2)
Perhaps by providing reason why using express.Router() is bad (beyond aesthetics), this approach could gain more traction. Just my 2 cents.
Thank you for your feedback @bartekus. I don't think express.Router() is bad per se. It absolutely legitimately exists. I came up with this package for another reason. File-based routing becomes more and more of an industry standard in the JS web framework community because of its benefits for developers when working in a team but also on solo projects.
File routing is much more intuitive, structured & effortlessly scalable. You won't need to bother about exporting & importing your router instances over and over again and making sure it's enqueued in the top level of your root app instance.
This is less about "aesthetics" rather than modularity.