Ajv JSON schema validation

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
now what is going on guys today we're going to talk about ajv which is a json schema validator that is particularly useful if you want to validate incoming payloads for your node server so it's somehow like an alternative to express validator yup or joy but the main difference is that it supports the json schema draft which is rfc8927 and that one is a cross-platform standardized way on how to describe like json types and that is interesting because technically speaking you could just share the json schema with another developer who's using a different programming language and if there's like a proper library out there then it shouldn't be a problem to or then that programmer can use the same validation yeah so that is what we want to do today i already prepared um an example project over here so it's a very simple server that oh yeah we spin up like an express server it has like one router um this router has like one endpoint which is register and we're just going to pretend that we want to register a user and what we want to do is we want to check whether first name email date of birth and country code is present and fulfills like a specific criteria yeah so this is what we want to do and the actual request in this example project is handled by this user controller which just returns a string so i'll put the code in the on github and the link in the description down below okay cool so this is where we start and we now want to get started with this ajv thing and the first thing we need to do is we need to install this so scroll down to here and as you can see you just need to run ajv npm install agv just one more note here there is another package it's called ajv formats and this one adds a couple of useful formats such as uh an email validator or like a hostname validator and so on and so on so they have basically split the functionality up so there's this core module which is ajv and then they have like this hiv formats which supports like a bunch of things like uri and date and time and so on and we will need this package as well so go ahead and npm install all of this yeah so i already have it installed but anyway i just ran the command again and yeah let's see how we can get started with this so if you go up to the top here of this readme here and you click on where is it here getting started you end up on this page and here it shows you like the minimal example right so you import this library you create a new instance of it and then you have like some schema so this is basically this json schema cross platform thing that we're using and then you compile this schema so you basically tell this library hey look i want you to take this schema and i want you i want you to give me a function that can very efficiently evaluate whether some javascript object or complies to this schema so to say yeah and then you can run it over here so this is how this works and the interesting thing here is that you will need to import this package and you will need to create an instance of this class and then you can also pass a specific option so let's maybe get started with that so let's go over here let's make a new directory and let's call this schema and yeah now that we have this thing let's just make a file and call this agv instance because we're only going to have one instance of this thing right and the the advantage of this is that we can configure agv how we want it so for example this is a very good property all errors true because that means that the validation will just not stop at one point once it encounters the first error but it will validate everything and that is very useful because after all you want to return all arrows to the front end otherwise it's very tedious right the user submits gets back one arrow then he gets back another error and it tries to submit again so that is just like really annoying cool so i'm just going to import this and what else we need we need to hook up this format library here and here's how this works so you import atv and then there's this method called add formats and then you just pass your instance to it and then it will hook up like all these formats inside of your agv instance and then it's going to work really well okay so let's add this function here and then you would say add formats and then ajv oh actually i have like a typo here right it's supposed to be ajv ajv instance yeah and that should pretty much do it so now we have this thing and let's just export it okay so here we go now we can work with that stuff and i already told you that we want to validate or we want to check for these fields now they're somewhat arbitrary but it's just an example so let's create a new file in here and let's call this the user schema and inside of here we're just going to import the agv instance and then we can define like our schema and there is also actually we can copy and paste that pretty much so let's take this let's paste it and you can see that this json this standardized schema here this json schema it does have like a few fields that are required so for one you need to say what type of object or what type you're validating so is it like an object is it a string if it is an object then it might have like properties and here you can define these properties okay and the properties that we want are say first name which is a string then we want let's see email which is also a string but which is supposed to be formatted as an email and by the way this formatter now is coming from these agv formats package so that's why we installed this thing in the first place date of birth is also a string and i want to show you something else this one is interesting it offers you the possibility to use enums so you can say something like okay i want to have a country code but obviously you cannot have whatever you want in this country code so the country actually needs to exist so here we could say okay we only allow the us and we only allow canada okay yeah and then outside of this you can specify which fields are required now i'm just going to take everything so i'll just say you need first name you need email you need date of birth and you need country code now we need to take the schema and compile it and the reason for that is that ajv is like very fast so if you give this schema to ajv it's going to put out like a super optimized validation function and this function will is then very very fast so this is also one of the or this is like a focus of this library that it is very fast in general we can just copy and paste this and say okay actually we just need to call agv instance in our case dot compile and this is what we can export yeah so that looks good yeah let's see how do we plug this thing in now well the easiest way would be to have some sort of middleware in here right so before the request goes to the controller we just run through some sort of middleware and then if there's like an issue then it's going to return like a bad request and that is very nice because that means we don't have to deal with any payload issues in our controllers because we have already validated everything so i'm going to make a new directory and then inside of this directory i will make a new file and i will call this validate dto so dto for data transfer object oops i should have named it uh dtojs yeah and what we're now doing might be a little bit weird at first but it's actually relatively straightforward so i'm going to make a function and this function itself is going to return another function so a function that returns a function and the reason is that this is somehow like our middleware factory so remember like a middleware is a function where you have a request a response and next as parameters and what we want to do is this function here you pa you give it like some compile schema which is actually a function so the output of this ajv dot compile is actually a function and then like when you give it like this this schema then you return a middleware that will just execute this function and this is what we will do in here right so we will just say const valid equals and then agv validate and then request a body so we're just going to say hey we have to find this schema just run this over the request body and if there's any issues please let us know and if this is false or falsy then we know okay there's like some sort of problem and then we return a bad request error and otherwise we just pass the control on to the next handler in the chain and now we have something that is really important and that is how to deal with errors in here because there's a little caveat and i just wanted to show you what i mean so this ajv instance like it's a function and this function has like a property it's called like errors if you run this function it might find some errors right and then this property points to the most recent errors so to the errors that correspond to the most recent run but then if you call this function again then it will point to another arrow somewhere in memory and that's why it's super important that we copy the reference to this error because otherwise if we run this thing again and now we get other errors then we would throw away the first reference the reason for that is mostly historical and the second reason is that it's much more efficient because if this thing were to return the error as an object then it would need to allocate an additional object right so it's just simpler to have it here as a pointer and this actually works simply because node is like single threaded so as long as we don't have like a weight in here it will all work and that's why it's so important so don't put like any await inside of here and then try to extract the errors so no matter what you do if you have any await you definitely definitely need to extract the errors first and that's why this is so important here that you say okay i'm going to copy the reference and then i will just say okay [Music] response.status400.json arrows so in this case it's not so much a problem here because we are immediately returning this this error but say if we had some error handling middleware and we were to throw an exception here or we were to say next with this error then we don't know what's happening later down the road right you could have an async and a weight and if this is the case and the server handles another request in the meantime then this errors object would be gone so that's why it is imperative that you copy like the reference to to this one and then once you have copied it it's safe to pass it on also i have like written some lengthy comment which i'm just going to copy and paste just that if someone finds this repository it's all fine okay yeah i think that's it pretty much why do we have this we don't need this and um yeah i think now the only thing that is left we need to go to our routes and then we can just plug this in right so we can say const validate dto what was it validate dto require middleware validate dto something like that right yeah and then we had validate dto and user schema okay and use a schema we need to import that as well so we will just say require [Music] schema user okay so now theoretically this should do something right so what we did is we plugged in an additional middleware for handling the request payload and let's just try this out so i'm just going to run npm run def and yeah it starts up so that is fine so let's pull open like a postman and let's go to the make like some post request to the register yeah let's just send this um oh and i see there's like a bad request and i saw i made like a mistake it must be country code like this right okay so now it should be fine if i now send this you can see okay nice i get the status 200 yeah i think you've already seen like the arrow message so say if i put like some property here now for this first name property is missing and now you get like a really nice error message back right say hey here's like this one is missing and it must be there because it's required so this is like really nice and the same happens or something similar happens if you say pass an invalid email then it also gives you this arrow right must match format email okay so that looks pretty good yeah and i think with this approach it's quite nice because you don't have to care in your controller about how to handle this request but you can still validate everything cool so that's it pretty much for ajv as you have seen it's a nice little library it's kind of cool that it uses uses this standardized json schema with the approach we have it's a very easy to maintain right because if you have more endpoints just add more things here in schema and just plug more things here in for the respective routes and yeah that's how i would use this library so thank you so much for watching leave a like and subscribe to the channel if you have any question about this let me know in the comments below also if you want to send me a tweet my twitter handle is at productioncoder so again thank you so much for watching and i'll see you next video bye
Info
Channel: productioncoder
Views: 10,449
Rating: undefined out of 5
Keywords: ajv json schema validation, ajv validation, ajv tutorial, ajv express middleware, ajv nodejs, node ajv example, ajv example, express ajv example, nodejs ajv example, ajv json example, ajv node setup, ajv express setup, ajv js validator, ajv validator, ajv schema, ajv schema validation example, ajv schema validation postman, ajv schema with key or id already exists, ajv all errors, ajv better errors, ajv demo, ajv json, ajv or joi, ajv openapi 3, ajv strict mode
Id: 9Pc8LGN4uug
Channel Id: undefined
Length: 14min 51sec (891 seconds)
Published: Mon Jul 19 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.