Sapper: [Feature request] server routes middlewares

Created on 26 Sep 2019  路  4Comments  路  Source: sveltejs/sapper

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:

  • it's easy to reason about
  • you can share and reuse piece of logic related to entities you use most commonly use in your server routes.
  • you can centralise easily error management in these middlewares, return 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) => {

    }
];
proposal

Most helpful comment

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) => {

    }]
)

https://www.npmjs.com/package/compose-middleware

All 4 comments

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) => {

    }]
)

https://www.npmjs.com/package/compose-middleware

@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.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Snugug picture Snugug  路  4Comments

UnwrittenFun picture UnwrittenFun  路  4Comments

keyvan-m-sadeghi picture keyvan-m-sadeghi  路  4Comments

benmccann picture benmccann  路  3Comments

BMorearty picture BMorearty  路  3Comments