You don’t always need to NOT reinvent the wheel

What if you want a wheel for your bicycle, and the only one available was created for a Boeing 747 aircraft?

Alan Berdinelli
4 min readSep 12, 2020

This is the story about how I created my own schema validation library: Schemy. I was writing a tiny API for a small app with a few friends. The packaged application weighted around 9 KB. I know, right? I told you. It was small.

Eventually, we needed to validate user input in the backend, so naturally, we came out with a few common validation library names we could use, such as Joi or AJV. The problem was their package size. The first one weighs around 500 KB, and the second one almost 1 MB!

This made us think, do we really need a library for just a few validations that weights like 110x times our app?

Let’s start from scratch

We want to validate an object. Something composed of keys and values. To validate what the value should be, we can assign to that key some properties to check for later. We wanted something simple, like mongoose’s schemas, but you know, without all the DB stuff. Something like this:

Our desired schema definition

Now that we know what we want, we can start coding it. We basically want a function that validates an input against this schema. In my case, I decided to write a class to keep the references more easily:

Schema constructor

Let’s think about that schema programmatically: We need to iterate over the schema keys and check if the input has all (and only) the declared keys and that their values match the configured types. Since we saved the schema in the instance, this can be done pretty easily by comparing each key of the input against that same key in the schema:

Our validate method

This is where the magic happens. We iterate over the schema using for…of and Object.entries() which allows us to get the keys and properties we configured when we first called our constructor. Then for each key, we check the type and finally if the one in the input matches that type. Of course, we save every error in an array, so we can return every validation error if there is more than one.

Our little library is alive!

Finishing the library

The basic functionality is done. We only support strings for now, but adding other native types is easy: just add more if blocks.

Well, having a lot of if blocks doesn’t look as sexy as we’d want. So there’s a trick we can use. Native types words like String, Number, or Boolean are actually functions. They return a value of that type. So you can take advantage of it combining typeof and these functions:

Implementation of typeof

If you remember in our basic schema, we set some properties for each key including the type, which can be either String, Number, Object, or Boolean. Since we passed actually a function, we can just call it and get the type of their return value. This allows us to improve our code and making it a lot smaller and smarter.

You can check by yourself in any javascript console to see how it works:

Example return of typeof with native constructor

Anyway…

Instead of automatically putting a library or framework in your project, try to check if you really need it first. There’s no need to grow your project with libraries that overkills your needs.

Try to find out what the dependency you’re adding does and what it does not. If it doesn’t do what you need, you’ll discard it for sure. But if it does hundreds of other things, maybe you should discard it as well and search for a smaller alternative, or why not, just do it yourself!

If you go for the DIY path, is a good idea to make it as generic as possible, and even open source! That way, you will receive help from the open-source community.

If you ever need a small validation library, you already know which one I recommend 😉

--

--

Alan Berdinelli

Fullstack developer focused in NodeJS, born in Argentina. Addicted to coffee and git.