Node-Typescript-Zod
In the following example will be creating a simple REST API, and validating it with zod.
You can contact me by telegram if you need to hire a Full Stack developer..
You can also contact me by discord Appu#9136.
creating our project
- open your terminal and type the following
- mkdir node-typescript-zod-tut
- cd node-typescript-zod-tut
- npm init --y
- code .
Packages
- express
- zod
- typescript
- ts-node-dev
- @types/express
Production packages
npm i express zod
Development packages
npm i typescript ts-node-dev @types/express -D
project file structure:
node-typescript-zod-tutorial/
├── node_modules/
├── src/
│ ├── routes/
│ ├── schema/
│ └── index.ts
├── tsconfig.json
└── package.json
Project setup
1- Add this line in your package.json
, with ts-node-dev we can run .ts files, --respawn to re-run automatically after a change in our file.
"scripts": {
"dev": "ts-node-dev --respawn src/index.ts"
},
2- Type the following line in your console,npx tsc --init
it will create a tsconfig.json, now in our tsconfig.json file let's use "ctrl+f" to find rootDir and outDir, uncomment rootDir and type this "rootDir": "./src",
uncomment outDir and type this "outDir": "./dist",
.
Let's code
1-creating our index.ts
index.ts
import express from 'express'
//initialiaztion
const app = express()
//server
app.listen(3000, () => {
console.log('listening on port 3000')
})
Now let's run npm run dev
and we should get this:
listening on port 3000
2- Let's go to our routes folder and create this file contacts.route.ts
contacts.route.ts
import { Router, Require, Response } from "express";
const route = Router()
route.post('/contacts', (req: Require, res: Response) => {
console.log(req.body)
res.json({message: 'contact created'})
})
export default route
Let's go back to index.ts and import our route.
index.ts
import express from 'express'
import contactsRoutes from './routes/contacts.routes'
//initialiaztion
const app = express()
//middlewares
app.use(express.json())
//routes
app.use(contactsRoutes)
//server
app.listen(3000, () => {
console.log('listening on port 3000')
})
let's try our API, I am gonna use the REST client VScode extension, but feel free to use postman, insomnia, or whatever you want.
We want to pass some fields, let's use contact first name, last name, email and a phone number.
3- Let's create our zod schema, go to our schema folder and create contacts.schema.ts file.
In this code we are creating our ContactSchema where firstName field should be a string with .string()
and cannot be empty using .nonempty()
.
contacts.schema.ts
import { z } from "zod";
export const ContactSchema = z.object({
firstName: z
.string()
.nonempty(),
})
Let's go back to contacts.route.ts
and import our schema.
import { Router, Request, Response } from "express";
import { ContactSchema } from "../schema/contacts.schema";
const route = Router()
route.post('/contacts',(req: Request, res: Response) => {
console.log(req.body)
try {
const result = ContactSchema.parse(req.body);
console.log(result)
res.json({messasge: 'contact created'})
} catch (error) {
return res.status(500).json({ message: error });
}
})
export default route
Let's try out our post route again and see what happens.
Now we are getting some errors, "expected": "string",
because "message": "Expected string, received number"
.
Let's fix a little bit our code to display our error message in a better way, first let's import ZodError
from zod, and change the catch block to display only the error messages from zod and if the error is not coming from zod display the server error
import { Router, Request, Response } from "express";
import { ContactSchema } from "../schema/contacts.schema";
import { ZodError }from "zod";
const route = Router()
route.post("/contacts", (req: Request, res: Response) => {
console.log(req.body);
try {
const result = ContactSchema.parse(req.body);
console.log(result);
res.json({ messasge: "contact created" });
} catch (error) {
if (error instanceof ZodError) {
return res
.status(400)
.json(error.issues.map((issue) => ({ message: issue.message })));
}
return res.status(500).json({ message: error });
}
});
export default route
Now we're getting this message .
Now let's the with firstName
field empty.
We can also change the error message, let's go back to contacts.schema.ts
, and add this to .nonempty()
import { z } from "zod";
export const ContactSchema = z.object({
firstName: z
.string()
.nonempty('first name is required'),
})
Now we're getting this.
Let's add the rest of the fields.
import { z } from "zod";
export const ContactSchema = z.object({
firstName: z
.string()
.nonempty('Name is Required'),
lastName: z
.string()
.nonempty('Last Name is Required'),
email: z
.string()
.email({message: 'Email is not valid'})
.nonempty('Email is Required'),
phone: z
.string()
.nonempty('Phone is Required'),
})
Let's do a couple of tests.
That would be a basic idea of validation with Zod.
You can contact me by telegram if you need to hire a Full Stack developer..
You can also contact me by discord..
I hope you find this helpful. please let me know what you think, thank you.
Top comments (0)