Skip to content

Feature Request: Revisit Issue #89 — Pass all HTTP request paths (/*) to the user function handler #451

Description

@mark-dropbear

Feature Request: Revisit #89 — Pass all HTTP request paths (/*) to the user function handler

Summary

Currently, faas-js-runtime hardcodes route registration to the root path (/) only. Any incoming HTTP request with a subpath (e.g., GET /api/users, GET /app.js, DELETE /items/123) is immediately intercepted by Fastify and rejected with a 404 Not Found response before the user's handle(context, body) function is ever invoked.

We would like to request revisiting Issue #89 and updating faas-js-runtime to pass all non-system HTTP paths to the user handler function by default.


Motivation & Comparison with Other Knative Function Runtimes

  1. Parity with Other Knative Language Runtimes:
    In other official Knative Functions runtimes (Go, Python, Rust, Quarkus/Java), all incoming HTTP requests regardless of path are forwarded directly to the function handler:

    • Go (kn func create -l go): The standard http.HandlerFunc receives all paths, and req.URL.Path is available.
    • Python (kn func create -l python): The Flask / CloudEvents invoker matches wildcard routes (/*) and exposes request.path.
    • Rust / Quarkus: Full URI path is preserved and passed to user code.

    The Node.js runtime is currently the only language implementation that restricts incoming traffic strictly to /.

  2. Knative Platform Alignment:
    Knative Serving (and Kourier/Contour/Istio ingress) already forwards full request paths directly to container port 8080. The 404 restriction is introduced solely by the faas-js-runtime wrapper package inside the container.

  3. Modern Serverless Use Cases:
    Restricting invocations to / prevents standard Node.js serverless patterns, such as:

    • RESTful APIs using standard URL path parameters (e.g., /api/user/:id/items).
    • Modern routing using standard web platform APIs like the URL Pattern API (URLPattern).
    • Micro-frontends or single-page applications (SPAs) that serve an HTML shell alongside static assets (/app.js, /style.css).
    • Webhook listeners requiring distinct callback paths.

Currently, developers wishing to use subpaths in Node.js Knative functions are forced to use non-standard workarounds, such as tunneling the intended path through custom headers (e.g., x-request-url), which breaks standard browser requests (<script>, <link>, fetch).


Technical Details

In lib/invocation-handler.js:

module.exports = function use(fastify, opts, done) {
  fastify.get('/', doGet);
  fastify.post('/', doPost);
  fastify.options('/', doOptions);
  ...

Because Fastify only has / registered in its route table, any request to /anything-else hits Fastify's default 404 handler and never invokes doGet / doPost.


Proposed Solution

  1. Register Wildcard / Catch-All Routes:
    In lib/invocation-handler.js, register catch-all routes (or fastify.all('/*', ...)), ensuring /metrics, /health/liveness, and /health/readiness remain prioritized:

    module.exports = function use(fastify, opts, done) {
      fastify.all('/*', doInvoke);
      fastify.options('/*', doOptions);
      ...
  2. Backwards Compatibility:

    • 100% Backwards Compatible: Existing functions that only receive root / requests will continue to behave identically.
    • Functions that inspect context.req.url or context.query will now receive real path data for all incoming requests.

Alternatives Considered

  • Custom reverse proxies / middleware: Adds unnecessary operational overhead and deployment complexity.
  • Header tunneling (x-request-url): Incompatible with standard browser asset loading and standard REST clients.
  • Hand-rolling custom HTTP servers: Bypasses faas-js-runtime entirely, losing built-in CloudEvent parsing, lifecycle hooks, and Knative CLI integration.

Thank you for maintaining this project!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions