---
url: https://fulmine.sndesign.it/examples/uws-route.md
description: >-
  A raw uWebSockets.js route with app.uws() in an Express app: µWS's own (res,
  req), no middleware, no Express layer.
---

# A raw µWS route next to your Express routes

`app.uws()` is a route served by uWebSockets.js with the handler as you wrote it: µWS's own `HttpResponse` and `HttpRequest`, with nothing of Express in front. The rest of the app stays Express.

From a clone of the repository:

```sh
cd examples && npm install
node uws-route.js
```

```js
// app.uws(): a route served by uWS itself, with the handler as written. It is called as
// (res, req) with uWS's own HttpResponse and HttpRequest, as a bare uWebSockets.js app would
// call it: no middleware, no Request, no Response. For the few routes where the Express API is
// not worth its cost; the rest of the application stays Express.
//
//   node uws-route.js
//   curl localhost:3000/health          ->  ok                 (raw)
//   curl localhost:3000/users/42        ->  {"id":"42"}        (raw)
//   curl localhost:3000/users/me        ->  {"id":"me"}        (raw: its pattern takes it first)
//   curl -X POST localhost:3000/users -H 'content-type: application/json' -d '{"name":"a"}'
//                                       ->  {"name":"a"}       (Express)
//   curl localhost:3000/slow?ms=200     ->  waited 200ms       (raw, answered late)
//   curl -F title=hi -F file=@uws-route.js localhost:3000/upload
//                                       ->  title (2 bytes), file uws-route.js (... bytes)
const express = require("fulmine.js"); // instead of require("express")

const app = express();

// no app.use() runs in front of a raw route: this logs the Express requests only
app.use((req, res, next) => {
    console.log("express", req.method, req.url);
    next();
});

// the whole answer in one call, as on uWS
app.uws.get("/health", (res) => {
    res.end("ok");
});

// a parameter is uWS's: read by index, or by name, off uWS's request
app.uws.get("/users/:id", (res, req) => {
    const id = req.getParameter(0) ?? "";
    res.writeStatus("200 OK").writeHeader("content-type", "application/json").end(JSON.stringify({ id }));
});

// written before the raw route or after it, this is never reached on GET: the raw pattern
// /users/:id takes /users/me first. `npx fulmine.js profile uws-route.js` says so
app.get("/users/me", (req, res) => res.json({ me: true }));

// another method on the same path is Express's
app.post("/users", express.json(), (req, res) => res.status(201).json(req.body));

// answering after the handler returns is the handler's business, as on uWS: read the request
// now, register onAborted, cork the late write
app.uws.get("/slow", (res, req) => {
    const ms = Math.min(Number(req.getQuery("ms")) || 100, 2000);
    let aborted = false;
    res.onAborted(() => {
        aborted = true;
    });
    setTimeout(() => {
        if (aborted) return;
        res.cork(() => {
            res.writeStatus("200 OK").end(`waited ${ms}ms`);
        });
    }, ms);
});

// uWS's own utilities are express.uWS, the instance this app serves with: getParts() splits a
// multipart body the handler collected itself
const { getParts } = express.uWS;
app.uws.post("/upload", (res, req) => {
    const contentType = req.getHeader("content-type");
    let aborted = false;
    res.onAborted(() => {
        aborted = true;
    });
    /** @type {Buffer[]} */
    const chunks = [];
    res.onData((chunk, isLast) => {
        // uWS reuses the chunk's memory once this returns, so it is copied
        chunks.push(Buffer.from(new Uint8Array(chunk)));
        if (!isLast || aborted) return;
        const parts = getParts(Buffer.concat(chunks), contentType) ?? [];
        const summary = parts.map(
            (p) => `${p.filename ? `${p.name} ${p.filename}` : p.name} (${p.data.byteLength} bytes)`
        );
        res.cork(() => {
            res.end(summary.join(", ") + "\n");
        });
    });
});

app.listen(3000, () => {
    console.log("http://localhost:3000/health");
});

```

See also: [Raw µWS routes](/uws-routes).
