Skip to main content
0
Software Development

สร้าง API พร้อม Validation ด้วย Express.js + Zod

สำหรับวันนี้เราจะมาอยู่กับ Library เจ๋ง ๆ ที่ชื่อว่า Zod สำหรับเอามาเช็คดูว่าค่าที่ส่งมานั้นถูกต้องตามที่เราได้กำหนดไว้หรือป่าว ถ้าถูกก็จะทำงานได้ แต่ถ้าไม่ถูกต้องมันก็จะแจก Error มาให้ ทำให้ลดโอการที่จะเกิดบั๊กจากข้อมูลที่ใส่มาไม่ถูกต้อง โดยในบทความนี้ จะพามาดูวิธีการใช้งานแบบ Step by step กันเลย ถ้าพร้อมแล้วเราไปลุยกันเลย!

Zod คืออะไร?

ก่อนอื่นมาทำความรู้จักกับ Zod ก่อนโดยมันคือ TypeScript Library ที่ใช้สำหรับตรวจสอบว่าข้อมูลที่รับมาและส่งออกไปนั้นถูกต้องตามที่เราต้องการรึป่าว เรียกง่าย ๆ ว่าเป็น Lib สำหรับการทำ Data Validation นั่นแหละ

ขั้นตอนการสร้าง API ที่ใช้ Zod โดยตัวอย่างนี้จะใช้ร่วมกับ Express.js และ TypeScript ก่อนอื่นเราก็จะต้องสร้างโปรเจกต์ขึ้นมาก่อน โดยการใช้คำสั่ง

mkdir express-zod-workshop
cd express-zod-workshop
npm init -y
JavaScript

แล้วก็ติดตั้ง package สำหรับโปรเจกต์นี้

npm install express body-parser zod
npm install --save-dev typescript @types/node @types/express ts-node nodemon
JavaScript

โปรเจกต์นี้เป็น TypeScript เราจะต้องสร้างไฟล์ tsconfig.json โดยสามารถสร้างไฟล์พร้อมค่าเริ่มต้นได้ด้วยคำสั่ง เมื่อไฟล์ tsconfig.json มาแล้ว ให้เราลองไปเช็คดูหน่อยว่า strict ตั้งเป็น true แล้วหรือป่าว เพื่อที่เราจะได้ใช้ความสามารถในการเช็ค Type ของ TypeScript ได้ด้วย

npx tsc --init
JavaScript

ต่อมาก่อนที่จะเริ่มเขียนโค้ดกัน เราจะต้องมาสร้างโครงสร้างของโปรเจกต์หน้าตาแบบนี้ก่อน

ต่อมาให้ไปที่จุดเริ่มต้นของการรันแอป โดยเราจะใช้ไฟล์ src/index.ts ทำการเรียกใช้ express body-parser สำหรับจัดการ JSON และกำหนด route โดยตอนนี้จะมีแค่เส้น /api/user ให้เชื่อมโยงกับ userRouter ที่จัดการฟังก์ชันการทำงานของ API ที่เกี่ยวข้องกับผู้ใช้

import express from 'express';
import bodyParser from 'body-parser';
import userRouter from './routes/userRoutes';

const app = express();
const PORT = 3000;

app.use(bodyParser.json());
app.use('/api/user', userRouter);

app.listen(PORT, () => {
  console.log(`Server is running on http://localhost:${PORT}`);
});
JavaScript

ต่อมาเราจะมาสร้าง Zod Schemas เอาไว้สำหรับจัดการข้อมูล โดย Zod Schemas จะเป็นโครงสร้างที่ใช้กำหนดรูปแบบข้อมูล ) ที่เราต้องการในโปรเจกต์เพื่อช่วยในการสร้างและตรวจสอบความถูกต้องของข้อมูล โดยเราจะเขียนไว้ในโฟลเดอร์ src/schemas สร้างไฟล์ userSchemas.ts

import { z } from 'zod';

export const userRegistrationSchema = z.object({
  username: z.string().min(3, "Username must have at least 3 characters"),
  email: z.string().email("Invalid email address"),
  password: z.string().min(8, "Password must have at least 8 characters"),
});

export const userLoginSchema = z.object({
  username: z.string(),
  password: z.string().min(8, "Password must have at least 8 characters"),
});
JavaScript

โดยโค้ดนี้จะเห็นได้ว่าเราใช้ Zod ในการสร้าง Schema ในการเช็คข้อมูล เราจะกำหนด Schema เอาไว้เลยว่าข้อมูลที่เข้ามาใน user registration และ user login จะต้องเป็นแบบไหน เช่นในโค้ดบอกว่า

userRegistrationSchema มีการกำหนดว่า username ต้องเป็นสตริงที่มีความยาวอย่างน้อย 3 ตัวอักษร, email ต้องเป็นอีเมลที่ถูกต้องตามรูปแบบ, และ password ต้องมีความยาวอย่างน้อย 8 ตัวอักษร

ส่วน userLoginSchema เป็น Schema ที่ใช้สำหรับตรวจสอบข้อมูลการล็อกอิน โดยกำหนดว่า username ต้องเป็นสตริง และ password ต้องมีความยาวอย่างน้อย 8 ตัวอักษร แล้วถ้าถามว่ามีอะไรที่เราต้องรู้ในการกำหนด Schema บ้าง

import { z } from 'zod';

const stringSchema = z.string(); // ค่าเป็น string
const numberSchema = z.number(); // ค่าเป็น number
const booleanSchema = z.boolean(); // ค่าเป็น boolean
const dateSchema = z.date(); // ค่าเป็น Date object
JavaScript

การเพิ่มข้อกำหนด (Constraints)

String

const schema = z.string()
  .min(3, "Must be at least 3 characters") // ความยาวขั้นต่ำ
  .max(10, "Must be at most 10 characters") // ความยาวสูงสุด
  .email("Invalid email address") // ต้องเป็นอีเมล
  .url("Invalid URL"); // ต้องเป็น URL
JavaScript

Number

const schema = z.number()
  .min(0, "Must be at least 0") // ค่าน้อยสุด
  .max(100, "Must be at most 100") // ค่าสูงสุด
  .int("Must be an integer"); // ต้องเป็นจำนวนเต็ม
JavaScript

Array

const schema = z.array(z.string()); // อาร์เรย์ที่มี string
const schemaWithMinMax = z.array(z.number()).min(1).max(5); // อาร์เรย์ของ number ที่มี 1-5 รายการ
JavaScript

Object

const schema = z.object({
  username: z.string().min(3),
  age: z.number().min(18),
  email: z.string().email(),
});
JavaScript

กลับมาที่ไฟล์ของเราต่อมาเราจะมาสร้าง Middleware สำหรับ Validation ให้ไปที่ โฟลเดอร์ src/middleware สร้างไฟล์ validationMiddleware.ts แล้วเขียนโค้ดเข้าไปดังนี้

import { Request, Response, NextFunction } from 'express';
import { z, ZodError } from 'zod';

export function validateData(schema: z.ZodObject<any>) {
  return (req: Request, res: Response, next: NextFunction) => {
    try {
      schema.parse(req.body);
      next();
    } catch (error) {
      if (error instanceof ZodError) {
        const errorMessages = error.errors.map(err => ({
          path: err.path.join('.'),
          message: err.message,
        }));
        res.status(400).json({ error: "Invalid data", details: errorMessages });
      } else {
        res.status(500).json({ error: "Internal Server Error" });
      }
    }
  };
}
JavaScript

โดย Middleware นี้จะหยุดการทำงานหากข้อมูลไม่ตรงกับ Schema และบอก Error ที่ตั้งไว้ออกมา เสร็จแล้วเราก็สามารถเรียกใช้ Middleware ใน Route ได้โดยไปที่ โฟลเดอร์ src/routes สร้างไฟล์ userRoutes.ts


import express from 'express';
import { validateData } from '../middleware/validationMiddleware';
import { userRegistrationSchema, userLoginSchema } from '../schemas/userSchemas';

const userRouter = express.Router();

userRouter.post('/register', validateData(userRegistrationSchema), (req, res) => {
  res.json({ message: "User registered successfully!", data: req.body });
});

userRouter.post('/login', validateData(userLoginSchema), (req, res) => {
  res.json({ message: "User logged in successfully!", data: req.body });
});

export default userRouter;
JavaScript

เท่านี้ก็เรียบร้อย! ตอนนี้ /api/user/register และ /api/user/login พร้อมใช้งานแล้ว รันเซิร์ฟเวอร์

npx ts-node-dev src/index.ts
JavaScript

แล้วลองยิง API ผ่าน Postman ได้เลย ตัวอย่างเส้น /api/user/register ด้วย POST Method แนบข้อมูลไปใน Body ดังนี้


{
  "username": "john",
  "email": "john@example.com",
  "password": "mypassword"
}
JavaScript

ถ้าข้อมูลถูกก็จะได้ข้อความว่า User registered successfully!

แต่ถ้าใส่ข้อมูลผิด Middleware ก็จะเอา Error มาถวายในทันที555

และนี่ก็เป็นตัวยอย่างการทำ API พร้อมกับการทำ Validation ไปพร้อม ๆ กันผ่าน Lib ของ TypeScript ยอดฮิตอย่าง Zod นั่นเอง

Sirasit Boonklang

Author Sirasit Boonklang

More posts by Sirasit Boonklang

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

    ประเภทของคุกกี้มีความจำเป็นสำหรับการทำงานของเว็บไซต์ เพื่อให้คุณสามารถใช้ได้อย่างเป็นปกติ และเข้าชมเว็บไซต์ คุณไม่สามารถปิดการทำงานของคุกกี้นี้ในระบบเว็บไซต์ของเราได้
    รายละเอียดคุกกี้

  • คุกกี้สำหรับการติดตามทางการตลาด

    ประเภทของคุกกี้ที่มีความจำเป็นในการใช้งานเพื่อการวิเคราะห์ และ นำเสนอโปรโมชัน สินค้า รวมถึงหลักสูตรฟรี และ สิทธิพิเศษต่าง ๆ คุณสามารถเลือกปิดคุกกี้ประเภทนี้ได้โดยไม่ส่งผลต่อการทำงานหลัก เว้นแต่การนำเสนอโปรโมชันที่อาจไม่ตรงกับความต้องการ
    รายละเอียดคุกกี้

บันทึกการตั้งค่า