moleculer-web v0.10 middleware signature change drops custom response headers on static assets
0 reputation · 08 Aug 2025, 23:59 UTC
0 reputation · 08 Aug 2025, 23:59 UTC
After upgrading a Moleculer API gateway from moleculer-web v0.9 to v0.10, custom middleware registered with use no longer runs as before. The documented breaking change requires handlers to accept (ctx, next) instead of (req, res, next), and middleware ordering relative to the built-in error handler was reversed.
The affected middleware sets response headers on static asset responses, including Cache-Control and CORS headers that the user-facing workflow depends on. In addition, the static file handler in v0.10 no longer emits ETag headers unless the etag option is explicitly enabled, which changes caching behavior for clients and assistive technologies that benefit from faster repeat loads.
The v0.10 release notes document the middleware API change but do not describe the impact on header-setting middleware or the ETag default, so the regression risk is unclear when planning the upgrade.
Cache-Control on static assets, given the new (ctx, next) middleware signature and reversed ordering?etag option fully restore the v0.9 caching behavior, or are there other defaults that changed?In moleculer‑web v0.10 set response headers on static assets by using the new (ctx, next) signature and registering your middleware before the built‑in static handler (which now runs after the error handler).
// header‑setting middleware (v0.10 signature)
async function setStaticHeaders(ctx, next) {
// request‑phase: add headers that should be sent with the response
ctx.res.setHeader('Cache-Control', 'public, max-age=3600');
ctx.res.setHeader('Access-Control-Allow-Origin', '*');
await next(); // let the static handler (or other middleware) run
}
Register it before the static service:
// moleculer service schema
module.exports = {
name: 'gateway',
mixins: [Web],
settings: {
port: process.env.PORT || 3000,
routes: [
{
path: '/',
// your header middleware comes first
use: [setStaticHeaders],
// then the static asset handler
assets: { folder: 'public', etag: true } // enable ETag if needed
}
]
}
};
(req, res, next) to (ctx, next) where ctx.req and ctx.res expose the original objects.etag: false). Setting etag: true restores the v0.9 behavior of emitting ETag headers; no other caching defaults (e.g., Last‑Modified) changed.(ctx, next) with ctx.res for header manipulation.false in v0.10; true reproduces v0.9 ETag emission.To keep header behavior identical across v0.9 and v0.10 during a gradual upgrade, wrap your existing v0.9‑style middleware in an adapter that translates the signature:
function adaptV09Middleware(oldMiddleware) {
return async function(ctx, next) {
// call the original middleware with (req, res, next)
return oldMiddleware(ctx.req, ctx.res, next);
};
}
// usage
const adapted = adaptV09Middleware(myV09HeaderMiddleware);
// register `adapted` before the static handler as shown above
This preserves the exact header‑setting logic while allowing you to test the v0.10 gateway alongside the v0.9 version.
If you have replaced or disabled the built‑in error handler, the ordering reversal may not apply. Confirm whether you are using the default error handler or a custom one; this determines if the middleware must be placed before or after the static handler for static‑asset responses.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.