Resty: a tiny, radix-tree based library for building RESTful APIs
Tags: typescript, javascript, node, opensource
Published: 2021-11-01 12:20:23


 A few days ago I posted about a library I made called [typed](https://github.com/brielov/typed) and it never happened to me before that people would actually use something I made. The thing is that I made `typed` to be a companion library to [resty](https://github.com/brielov/resty) which is a thin wrapper around Node's http core module.

Resty is what I think is the best way I'd like to write RESTful APIs in Node. It borrows some of its syntax from the fetch API and it is of course type-safe. Let me show you how I'd like to write my endpoints.

![Code demonstration](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8n9q3nji6duoofjiwhud.png)

Having an endpoint of about three lines of code is pretty nice to me, specially because there's type-safety involved. Take a closer look at `request.json` and `request.query`. They both require a `typed` function to be passed in. If the validation fails, a `400 Bad Request` error is returned with a detailed explanation of what went wrong.

Also, `postMovie` and `getMovies` are typed because it is inferring the types from the `Response` object, so it knows that getMovies returns a `Response<Movie[]>` and postMovie returns a `Response<Movie>`.

The example above shows multiple endpoints being written in a single file. I personally don't don't use it like this (I prefer to write endpoints in separate files) but for demonstration purposes I'll leave it like this.

So how do we glue the endpoints together? Well, we can use the `createHandler` function to combine all our endpoints into a single request handler that can be use directly with `http.createServer`. `createHandler` will build a radix-tree based router internally which was borrowed and adapted from [koa-router-tree](https://github.com/steambap/koa-tree-router) which is the fastest router implementation out there, even faster than fastify's [find-my-way](https://github.com/delvedor/find-my-way).

```typescript
import { createServer } from "http";
import { createHandler } from "resty";
import { postMovie, getMovies } from "./endpoints";

const handler = createHandler(postMovie, getMovies);
const server = createServer(handler);

server.listen(4000, () => console.log("Listening on port 4000"));
```

Right now you're thinking "but this doesn't support middleware, how would I enable cors?" Well, `resty` is just a good old request handler, so you could actually combine it with [connect](https://github.com/senchalabs/connect).

```typescript
// app.ts

import connect from "connect";
import logger from "morgan";
import cors from "cors";
import { createHandler } from "resty";
import { postMovie, getMovies } from "./endpoints";

const handler = createHandler(postMovie, getMovies);

export const app = connect();

app.use(logger("dev"));
app.use(cors());
app.use(handler);
```

The nice thing about doing things this way is that you can test your endpoints the same way you would test an express application with `supertest`.

I know all cool kids are writing Serverless APIs these days, but I still enjoy writing APIs the old way for simple, personal projects. Anyways, I thought of sharing this library too and hope somebody will benefit from it. 

Cheers!

{% github brielov/resty %}