README
THIS PROJECT HAS BEEN DEPRECATED Please check out htts
Fast as fuck, easy to use http server written in typescript
Faf takes inspiration from the fetch
API. It is simple and expressive, it has a very small footprint and it is also very performant. Simplicity is what it does well. Take a look at the example repo.
Installation
$ npm install faf
Usage
import { HttpServer, HttpStatus, Response } from "faf";
const http = new HttpServer();
http.post("/products", async (request) => {
// You should validate this with your library of choice
const body = await request.json();
const product = await prisma.product.create(body);
return Response.json(product, HttpStatus.Created);
});
const { port } = await http.bind(4000);
console.log(`Listening on port ${port}`);
Dynamic and Query Params
Faf normalizes both query and dynamic params into a single URLSearchParams
instance. note: dynamic params override query string params.
// incoming url: /products/5?limit=10
http.get("/products/:id", (request) => {
const { url } = request;
console.log(url.pathname); // /products/5
console.log(url.searchParams); // URLSearchParams { 'id' => '5', 'limit' => '10' }
});
CORS
Faf comes with cors
support out of the box. It is a fair simple implementation (for now) taken mostly from @koa/cors
and expressjs/cors
.
const http = new HttpServer({ cors: true });
// or
const http = new HttpServer({
cors: { origin: "https://example.com", allowedHeaders: ["x-token"] },
});
Sockets
Faf is built around Node's core http module. It exposes the underlying server so it can be used alongside websocket libraries, such as Socket.IO or ws.
Socket.IO
import { HttpServer } from "faf";
import { Server as SocketServer } from "socket.io";
const http = new HttpServer();
const io = new SocketServer(http.server, {
/* other options */
});
io.on("connection", (socket) => {
// work your magic
});
await http.bind(4000);
WS
import { HttpServer } from "faf";
import { WebSocket } from "ws";
const http = new HttpServer();
// Create a WebSocket server completely detached from the HTTP server.
const wss = new WebSocket.Server({ clientTracking: false, noServer: true });
http.server.on("upgrade", (request, socket, head) => {
// Nice place to do some authentication
wss.handleUpgrade(request, socket, head, (socket) => {
wss.emit("connection", socket, request);
});
});
wss.on("connection", (socket, request) => {
// Work your magic...
});
await http.bind(4000);
Benchmarks
Command
bombardier -c 126 -n 1000000 http://localhost:4000/example
Code
import { HttpServer, Response } from "faf";
const http = new HttpServer();
http.get("/example", () => Response.text("Hello world"));
http.bind(4000);
Output
Statistics Avg Stdev Max
Reqs/sec 26228.48 1717.36 28772.79
Latency 4.69ms 197.48us 19.60ms
HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 5.73MB/s
Here's the ouput for the express
equivalent.
Statistics Avg Stdev Max
Reqs/sec 8880.65 839.30 9964.55
Latency 14.19ms 0.93ms 69.20ms
HTTP codes:
1xx - 0, 2xx - 1000000, 3xx - 0, 4xx - 0, 5xx - 0
others - 0
Throughput: 2.60MB/s