Skip to content

Plugin api: raw-body mode for plugins that wrap node-style handlers #583

Description

@melvincarvalho

Split out of #206 (plugin-zero results comment): second seam forced by mounting Tideholm inside JSS.

Problem

Fastify's content parsers consume the request stream before handlers run. A plugin that hands requests to an existing node-style handler ((req, res) — any wrapped HTTP app, reverse proxy, or framework adapter) then blocks forever: the wrapped app listens for data/end on a stream that has already been drained. This cost an hour of debugging in the Tideholm adapter and will bite every plugin of this shape.

Workaround today (works, but is folklore)

Scoped registration with a pass-through parser, plus reply.hijack():

await fastify.register(async (scope) => {
  scope.removeAllContentTypeParsers();
  scope.addContentTypeParser('*', (req, payload, done) => done(null, payload));
  scope.all(prefix, handler);       // handler: reply.hijack(); app.handle(request.raw, reply.raw)
  scope.all(prefix + '/*', handler);
});

Proposal

When the #206 loader lands, api.fastify (or a helper like api.mountApp(prefix, nodeHandler)) should offer this as a declared mode — e.g. rawBody: true in the plugin manifest or register options — so plugin authors never rediscover the scoped-parser incantation. api.mountApp is the stronger shape: it can bundle the prefix registration, the parser escape, the hijack, and the appPaths WAC exemption (see sibling issue) into one call, since every wrapped-app plugin needs all four together.

Acceptance

  • A plugin can declare/mount a node-style handler and receive unconsumed request bodies
  • Host content parsing unaffected outside the plugin's scope
  • Test: JSON POST through a mounted node handler round-trips (the exact Tideholm demo case)
  • Documented in the plugin-author docs alongside Plugin system for JSS #206's manifest format

Metadata

Metadata

Assignees

No one assigned

    Labels

    pluginCould be implemented as a plugin (#206); core/plugin line defined in #564

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions