DEV Community

Cover image for Introducing Catena ⛓️ – a Library for building type-safe Express Handlers
Eyk
Eyk

Posted on

Introducing Catena ⛓️ – a Library for building type-safe Express Handlers

Today, we're launching a new framework/library that helps you building type-safe handlers for Express.js based applications, called Catena!

🔎 https://github.com/sonic-technology/catena

Catena features zod-powered request validations, type-safe middlewares, monorepo type sharing & much more.

The following is what a handler might look like. It includes validations for parameters & headers, two middlewares and a response transformer that creates a secure DTO. All in one easy to understand function chain.

Best of all, it can be dropped into any Express application in an isolated way, so you don't have to rewrite your whole application if you want to try it with an existing application..

import { Handler, HTTPError } from '@sonic-tech/catena'
import { z } from 'zod'

app.get(
    '/user/:uuid',
    new Handler().
        .validate('params', {
            uuid: z.string().uuid()
        })
        .validate('headers', {
            authorization: z.string()
        })
        .middleware((req) => {j
            const requestingUser = await SecurityService.getAuthorizedUser(req.headers.authorization);
            if (!requestingUser) {
                // Throw errors when you want to stop further request processing while returning an error at the same time
                throw new HTTPError(400, 'This should fail')
            }

            return {
                requestingUser
            }
        })
        .middleware(AnotherMiddleware)
        .resolve(async (req, res, context) => {
            // You can access the merged type-safe context of all middlewares in the resolver
            const { requestingUser } = context


            const userIncludingPassword = await UserService.getUser(req.uuid)

            return userIncludingPassword
        })
        .transform((data) => {
            return {
                data: {
                    uuid: data.uuid,
                    email: data.email
                }
            }
        })
        .express()
)
Enter fullscreen mode Exit fullscreen mode

Try it out: https://github.com/sonic-technology/catena

I would love to hear your thoughts in the comments!

Top comments (0)