Description
When migrating express based app to sapper, I always feel that I am missing something...
What is nice in express is the ability to add _route-based_ middlewares such as in the below example:
app.get("/api/accounts/:accountId/document/:documentId",
haveValidAccountId, // Could read accountId, fetch corresponding account, and put it in req
haveValidDocumentId, // Same here
(req, res) => {
// route code goes here
// req.account and req.document could be here thanks to these middlewares
}
)
This is convenient for several reason:
next(error) if necessary.So back in sapper, I really like the simplicity of defining filesystem routes, where you just implement the corresponding HTTP verb. This is a nice feature. 馃憤
Here is my above example, I would have such a server route
/routes/api/accounts/[accountId]/document/[documentId].js
export async function get(req, res) {
// I want to write that code only once in a middleware, and be able to reuse it
const { accountId, documentId } = req.params;
if (accountId) {
try {
const account = await db.getAccount(accountId);
} catch (err) { /*... */ }
}
}
Proposition
What about introducing this syntax:
import {hasValidAccount, hasValidDocument} from "./middlewares";
// Standard server route, with no middleware
export function get(req, res) {}
// Adding middlewares via array syntax
export const get = [
hasValidAccount,
hasValidDocument,
(req, res) => {
}
];
I tend to put my middleware in server.js, but you could do this: (untested)
import { compose } from 'compose-middleware'
import { hasValidAccount, hasValidDocument } from "./middlewares"
export const get = compose([
hasValidAccount,
hasValidDocument,
(req, res) => {
}]
)
@thgh thanks! 馃憤 it fits perfectly my need. I didn't know about this compose-middleware.
I'll test, if working, I'll close the issue.(But I really don't see why it would not be working)
And some syntax for like entire /api route. We can do this with src/routes/api/index.js for example. Also something that handles all http words like app.use().
I think a syntax like would be very near to express and look nice:
export const post = [
myFirstMiddleware,
mySecondMiddleware,
myThirdMiddleware,
(req, res, next) => { ... },
];
Also for the app.use() part, to specify a middleware for all HTTP methods, we need something else as well. Maybe some sort of syntax like this?
export const use = [
myFirstMiddleware,
mySecondMiddleware,
myThirdMiddleware,
(req, res, next) => { ... },
];
// Maybe for only one middleware, we can do something this as well:
export function use(req, res, next) { ... }
Or
export default [
myFirstMiddleware,
mySecondMiddleware,
myThirdMiddleware,
(req, res, next) => { ... },
];
// Maybe for only one middleware, we can do something this as well:
export function (req, res, next) { ... }
Or maybe
// can be singular too
export const middlewares = [
myFirstMiddleware,
mySecondMiddleware,
myThirdMiddleware,
(req, res, next) => { ... },
];
// Maybe for only one middleware, we can do something this as well:
export function middlewares(req, res, next) { ... }
Also we really need error handing for server routes.
Most helpful comment
I tend to put my middleware in server.js, but you could do this: (untested)
https://www.npmjs.com/package/compose-middleware