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.
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"));
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);
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!
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)