npm package: @j-o-r/apiserver
Description: Fast, slim REST API server / socket server
Author: Jorrit Duin
Latest version: 2.1.6

# @j-o-r/apiserver

A lightweight Node.js module for creating HTTP and WebSocket servers with API controllers.

## Description

This module provides tools to build HTTP servers that expose API endpoints via controller objects. It includes support for WebSockets, request handling with `ClientWrapper`, file serving, form parsing, streaming, and more. Built for simplicity and tested with various scenarios.

**Version**: 2.1.5

## Installation

```bash
npm install @j-o-r/apiserver
```

## Usage

Import and create a server with a controller object:

```javascript
import { server } from '@j-o-r/apiserver';

const MyController = {
  index: async (client) => {
    await client.serve(200, { message: 'Hello World' });
  }
};

await server.create('api', { port: 8080, host: '127.0.0.1' }, MyController);
// http://127.0.0.1:8080/api/index
```

### Key Components

- **server.create(name, options, controller)**: Starts an HTTP server.
  - Options: `port` (number, default 80), `host` (string, default 'localhost'), `ws` (WebSocketServer instance), `strict` (boolean), `verbose` (boolean), `debug` (boolean).
- **server.delete()**: Stops the running server gracefully.
- **ClientWrapper** (typed as `Client`): Handles requests with methods for response, data retrieval, etc.
- **WebSocketServer**: For WebSocket handling with connection management, messaging, etc.
- **request(url, method, headers, body)**: Utility for testing requests, supporting various response types.

## Examples

### HTTP Server

```javascript
import { server, ClientWrapper } from '@j-o-r/apiserver';

const Controller = {
  echo: async (client) => {
    const data = await client.getPost();
    await client.serve(200, data);
  }
};

await server.create('test', { port: 9022, host: '127.0.0.1' }, Controller);
```

### WebSocket Server

```javascript
import { WebSocketServer } from '@j-o-r/apiserver';

const ws = new WebSocketServer({
  onMessage: (conn, msg) => { /* handle */ },
  onConnection: (conn) => true
});

// Attach to HTTP server
await server.create('ws', { port: 9022, host: '127.0.0.1', ws }, Controller);
```

### Streaming Response

```javascript
stream: async (client) => {
  client.writeHeaders(200);
  client.write('[');
  for (let i = 0; i < 10; i++) {
    client.write(JSON.stringify({ id: i }) + (i < 9 ? ',' : ''));
  }
  client.write(']');
  await client.end();
}
```

## API

### Server
- **create(namespace, options, app)**: Starts HTTP server exposing app methods under namespace.
- **delete()**: Stops the server.

### ClientWrapper (Client)
Methods for handling HTTP requests:
- `serve(status, data, lastModified?)`: Send JSON response.
- `serveFile(file, mime?)`: Serve a file.
- `serveFolder(folder, serveData?)`: Serve a folder (optionally with content).
- `getPost(form?, maxSize?)`: Get POST data (JSON or form).
- `method()`: Get HTTP method.
- `remoteAddress()`: Get client IP.
- `parameters()`: Get URL parameters.
- `query()`: Get query params.
- `id`: Getter for unique connection ID.
- `ctime`: Getter for creation timestamp.
- `url()`: Get request URL path.
- `requestUrl()`: Get full request URL.
- `pipe(stream)`: Pipe stream to response.
- `getRequestHeader(key)`, `getRequestHeaders()`: Access incoming headers.
- `addHeader(key, value, override?)`, `deleteHeader(key)`, `getHeader(key)`: Manage outgoing headers.
- `writeHeaders(status)`, `write(message)`, `end()`: Low-level response writing.

### WebSocketServer
- **Constructor(options)**: Options include `verbose`, `pingInterval`, `pongTimeout`, `onConnection`, `onMessage`, `onClose`, `onError`.
- **initialize(httpServer)**: Attach to HTTP server.
- **sendToConnection(id, message)**: Send to specific connection.
- **broadcast(message, filter?)**: Broadcast to all (or filtered) connections.
- **getConnections()`: Get all connections.
- **getConnection(id)`: Get specific connection.
- **closeConnection(id, code?, reason?)**: Close a connection.
- **shutdown()`: Shutdown server.

### Request Utility
- **request(url, method?, headers?, body?)**: Make HTTP requests. Returns `{ status, response, headers, responseType }` where `responseType` is 'none', 'text', 'js', or 'blob'.
- **request.toBlob(formData)**: Convert FormData to Blob.

See `scenarios/` directory for comprehensive examples.

## Contributing

Pull requests welcome. Fork and submit.

## License

Apache License, Version 2.0