DEV Community

Gabriel Vaquer
Gabriel Vaquer

Posted on

Resty: a tiny, radix-tree based library for building RESTful APIs

A few days ago I posted about a library I made called 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 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

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 which is the fastest router implementation out there, even faster than fastify's find-my-way.

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"));
Enter fullscreen mode Exit fullscreen mode

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.

// 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);
Enter fullscreen mode Exit fullscreen mode

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 logo brielov / resty

Syntactic sugar for RESTful APIs

resty

Syntactic sugar for RESTful APIs.

resty adds a very thin layer on top of Node's core http module that provides a beautiful, simple, and easy to use API for building RESTful APIs. It is mostly syntactic sugar, but it also provides a few additional features.

  • A really fast, radix-tree based routing system that allows you to define routes in a declarative way.
  • A simple and powerful way to validate request parameters and JSON payloads using typed (direct dependency).
  • Built-in error handling that automatically generates error responses for you.
  • Separation of concerns: write your http handlers in a modular way, and use the createHandler function to glue them all together.
  • Type-safe request and response objects.

Note that at the time of writing resty has not been fully tested in the real world and is not recommended for production use (yet). You can play around with it on small, personal projects…

Top comments (0)