npm package: @nxtedition/http
Description: HTTP/HTTP2 server middleware framework with priority-based scheduling, request lifecycle tracking, and Koa-style middleware composition.
Latest version: 1.1.7

# @nxtedition/http

HTTP/HTTP2 server middleware framework with priority-based scheduling, request lifecycle tracking, and Koa-style middleware composition.

## Install

```bash
npm install @nxtedition/http
```

## Usage

### Basic Server

```js
import { createServer } from '@nxtedition/http'

const server = createServer({ keepAliveTimeout: 120_000 }, { logger: pino() }, (ctx) => {
  ctx.res.writeHead(200, { 'content-type': 'text/plain' })
  ctx.res.end('Hello World')
})

server.listen(3000)
```

### Middleware Composition

```js
import { createServer, compose } from '@nxtedition/http'

const auth = async (ctx, next) => {
  if (!ctx.req.headers.authorization) {
    const err = new Error('Unauthorized')
    err.statusCode = 401
    err.expose = true
    throw err
  }
  await next()
}

const handler = async (ctx) => {
  ctx.res.writeHead(200)
  ctx.res.end(JSON.stringify({ user: 'authenticated' }))
}

const server = createServer({ logger: pino() }, [auth, handler])
```

### Priority-Based Scheduling

Requests are automatically prioritized based on the `nxt-priority` header or user-agent detection. Priority maps to DSCP/ToS values on the socket:

| Priority | Value | DSCP | Use Case         |
| -------- | ----- | ---- | ---------------- |
| highest  | 3     | EF   | Realtime         |
| higher   | 2     | AF41 | High priority    |
| high     | 1     | AF31 | User experience  |
| normal   | 0     | BE   | Default traffic  |
| low      | -1    | LE   | Background tasks |
| lower    | -2    | LE   | Replication      |
| lowest   | -3    | LE   | Batch jobs       |

### Error Handling

Thrown errors are automatically serialized to HTTP responses:

```js
const handler = (ctx) => {
  const err = new Error('Validation failed')
  err.statusCode = 422
  err.body = { errors: [{ field: 'email', message: 'required' }] }
  err.headers = { 'x-request-id': ctx.id }
  throw err
}
```

Error properties:

- `statusCode` - HTTP status code (default: 500)
- `body` - Response body (object, string, or Buffer)
- `headers` - Additional response headers (object or flat array)
- `expose` - If `true`, includes `err.message` as JSON response body

### Context Factory

```js
import { createServer, Context } from '@nxtedition/http'

const server = createServer((req, res) => {
  const ctx = new Context(req, res, logger)
  ctx.db = database
  return ctx
}, handler)
```

### AbortSignal Support

```js
const handler = async (ctx) => {
  // ctx.signal is aborted when the request errors or is aborted
  const data = await fetch('http://upstream/api', { signal: ctx.signal })
  ctx.res.writeHead(200)
  ctx.res.end(await data.text())
}
```

## API

### `createServer(ctx, middleware?)`

### `createServer(options, ctx, middleware?)`

Creates an HTTP server with enhanced request/response classes.

- **options** - Server options (extends `http.ServerOptions`)
  - `logger` - Pino-compatible logger
  - `signal` - `AbortSignal` for graceful shutdown
  - `socketTimeout` / `timeout` - Socket timeout (default: 120s)
- **ctx** - Context config object `{ logger, ...opaque }` or factory function `(req, res) => Context`
- **middleware** - Handler function or array of middleware functions

### `compose(...middleware)`

Composes middleware functions into a single middleware. Supports arrays and variadic arguments. In development mode, validates that `next()` is not called multiple times and that middleware properly awaits downstream.

### `Context`

Request context wrapping `req` and `res` with:

- `id` - Unique request ID
- `req` - `IncomingMessage` instance
- `res` - `ServerResponse` instance
- `target` - Parsed URL target (protocol, hostname, port, pathname, search)
- `query` - Parsed query parameters
- `userAgent` - User-Agent header value
- `priority` - Resolved request priority
- `signal` - `AbortSignal` (lazily created)
- `logger` - Child logger with request ID

### `IncomingMessage`

Extended `http.IncomingMessage` with computed `id`, `target`, and `query` properties. Results are lazily cached and invalidated when URL or host changes.

### `ServerResponse`

Extended `http.ServerResponse` with:

- `timing` - Request timing metrics (created, connect, headers, data, end)
- `bytesWritten` - Total bytes written to response
- Custom header tracking that is independent of Node.js internals

### `requestMiddleware(ctx, next)`

Core middleware that handles request lifecycle:

- Sets `request-id` response header
- Fast-dumps GET/HEAD request bodies
- Tracks pending requests
- Serializes errors to HTTP responses
- Logs request lifecycle events

### `upgradeMiddleware(ctx, next)`

Middleware for WebSocket/upgrade request handling with lifecycle logging.

### `genReqId()`

Generates unique request IDs using V8 SMI-optimized integers (`req-{base36}`).

## License

MIT