Routing
Basic routing concept
Dotpress provides you with a defineRoute
function to declare your endpoints. Let's see the example below:
defineRoute({
path: '/articles',
method: 'get', // Optional, default: get. Allowed values: get | post | put | delete
handler: async ({ req, res }) => {
// It's your main handler function.
// Handler context receives req and res: Request and Response objects from Express.
// returned Value will be sent to client as JSON by default
return [
{ title: 'Intro', href: '/intro' },
{ title: 'Quickstart', href: '/quickstart' },
]
}
})
Splitting your routes
Of course, you will not have all of your routes defined in a single index.ts file. You will probably split them in multiple files, organized by entity types or by features.
When you are calling defineRoute
, your route is automatically registered in a router registry. Therefore, unlike standard express application, you don't need to import a router or whatsoever.
However, you still need to make sure to import all files declaring routes before starting your app.
Let's consider the following project structure:
/src
/handlers
auth.ts
articles.ts
authors.ts
members.ts
routes.ts
index.ts
Your setup will look like:
// index.ts
import { createApp, defineRoute } from 'dotpress'
import './routes'
const app = await createApp({
// Optional app options here...
})
app.listen(3000, () => {
console.log('Server listening on port 3000')
})
// routes.ts
import './handlers/auth.ts'
import './handlers/articles.ts'
import './handlers/authors.ts'
import './handlers/members.ts'
Route Groups
Dotpress allows you to group your routes in order to apply common prefix and/or middlewares. It can be useful
Dotpress allows you to group routes using a shared URL prefix and common middlewares. This is especially useful to organize your application by domain (e.g. /admin
, /auth
, /billing
) or to version your API (e.g. /v1
, /v2
).
Basic usage:
const adminGroup = createRouteGroup('/admin', [requireAdminRole]);
adminGroup.defineRoute({
method: 'get',
path: '/users',
handler: async () => [{ id: 1, name: 'Alice' }]
});
This will create a route accessible at /admin/users
with the requireAdminRole
middleware applied.
You can also define nested groups using group.createGroup()
:
const adminGroup = createRouteGroup('/admin', [requireAdminRole]);
const billingGroup = adminGroup.createGroup('/billing', [requireBillingAccess])
billingGroup.defineRoute({
method: 'post',
path: '/invoices',
handler: async () => ({ created: true })
});
This will result in a route: POST /admin/billing/invoices
with middlewares: [requireAdminRole, requireBillingAccess]
.