HTTS
Expressive, easy to use, zero-dependency http server written in typescript
Htts takes inspiration from the fetch
API. It is simple and expressive, it has a very small footprint and it is also very performant. Take a look at the example repo.
Warnings
Htts relies heavily on the typescript compiler. If you make typescript happy, you make Htts happy. Keep in mind that if you are using Htts with plain javascript, it will not make any runtime type-checking. We recommend using it on typescript-only projects with strictNullChecks
set to true
inside your tsconfig.json
file.
Installation
$ npm install htts
Usage
import { HttpServer, HttpStatus, Response } from "htts";
const htts = new HttpServer();
htts.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 htts.bind(4000);
console.log(`Ready on port http://localhost:${port}`);
With Next.js
Why would you want to use htts
with Next.js?
- No more
if method === 'POST'
statements - Expressive and familiar syntax
- Catches
HttpError
and replies accordingly - Lightweight wrapper
// pages/api/posts.ts
import { post } from "htts/next";
import { Response, HttpStatus } from "htts";
import { PageConfig } from "next";
// This is important since htts does the parsing by itself.
// If you forget this and try to read the body, a `400` error will be thrown.
export const config: PageConfig = {
api: {
bodyParser: false,
},
};
export default post(async (request) => {
const body = await request.json();
return Response.json(body, HttpStatus.Created);
});
Dynamic and Query Params
Htts normalizes both query and dynamic params into a single URLSearchParams
instance. note: dynamic params override query string params.
// incoming url: /products/5?limit=10
htts.get("/products/:id", (request) => {
const { url } = request;
console.log(url.pathname); // /products/5
console.log(url.searchParams); // URLSearchParams { 'id' => '5', 'limit' => '10' }
});
CORS
Htts 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 htts = new HttpServer({ cors: true });
// or
const htts = new HttpServer({
cors: { origin: "https://example.com", allowedHeaders: ["x-token"] },
});
Uploads
Htts has multipart/form-data support through multiparty.
const htts = new HttpServer();
htts.post("/upload", async (request) => {
const { fields, files } = await request.formData();
// Work your magic
return Response.status(HttpStatus.Created);
});
Sockets
Htts 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 "htts";
import { Server as SocketServer } from "socket.io";
const htts = 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 "htts";
import { WebSocket } from "ws";
const htts = new HttpServer();
// Create a WebSocket server completely detached from the HTTP server.
const wss = new WebSocket.Server({ clientTracking: false, noServer: true });
htts.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 htts.bind(4000);
Benchmarks
Command
bombardier -c 126 -n 1000000 http://localhost:4000/example
Code
import { HttpServer, Response } from "htts";
const htts = new HttpServer();
htts.get("/example", () => Response.text("Hello world"));
htts.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