วิธีสร้าง Backend API ด้วย NitroJS

Ashley Goolam

Ashley Goolam

19 January 2026

วิธีสร้าง Backend API ด้วย NitroJS

Apidog สำหรับองค์กร

ติดตั้งภายในองค์กร

SSO & RBAC

รองรับ SOC 2

สำรวจ Apidog Enterprise

เมื่อผมสร้าง API ที่ใช้งานจริงครั้งแรก ผมใช้ Express.js และใช้เวลาติดตั้งประมาณสองชั่วโมง: โค้ดเริ่มต้น, มิดเดิลแวร์, แฮนเดอร์เส้นทาง, การกำหนดค่า TypeScript และสคริปต์การดีพลอย เมื่อเร็วๆ นี้ ผมได้สร้าง REST API ที่สมบูรณ์ได้ในเวลาเพียง 20 นาทีโดยใช้ NitroJs ไม่มีการเชื่อมโยง app.use(), ไม่มีการกำหนดเส้นทางด้วยตนเอง, ไม่มีปัญหาในการดีพลอย

คู่มือนี้จะแสดงให้คุณเห็นว่า NitroJs ช่วยลดโค้ดเริ่มต้นได้อย่างไร พร้อมมอบแบ็กเอนด์ที่พร้อมใช้งานจริง ซึ่งทำงานได้ทุกที่ ไม่ว่าจะเป็น Node, Bun, Deno, serverless หรือ edge

NitroJs คืออะไร และทำไมจึงควรใช้สำหรับแบ็กเอนด์ API?

NitroJs เป็นชุดเครื่องมือเซิร์ฟเวอร์จาก ระบบนิเวศ UnJS ที่ถือว่าแบ็กเอนด์ของคุณเป็น build artifact แทนที่จะเขียนเซิร์ฟเวอร์ที่ผูกติดกับรันไทม์ คุณเขียนแฮนเดอร์เส้นทางและ Nitro จะคอมไพล์เป็นชุดรวมที่พกพาได้ สามารถดีพลอยโค้ดเดียวกันไปยัง Node.js, Cloudflare Workers, Vercel หรือคอนเทนเนอร์ Docker ได้โดยไม่ต้องเปลี่ยนแม้แต่บรรทัดเดียว

NitroJs สำหรับแบ็กเอนด์ API

โมเดลหลัก: เขียนเส้นทาง ไม่ใช่เซิร์ฟเวอร์ คุณมุ่งเน้นที่ตรรกะของ API; Nitro จัดการ HTTP, มิดเดิลแวร์ และส่วนเชื่อมต่อแพลตฟอร์ม

ข้อดีหลักสำหรับแบ็กเอนด์ API:

สำหรับนักพัฒนา API นี่หมายความว่าคุณสามารถส่งมอบงานได้เร็วขึ้นและปรับโครงสร้างโค้ดน้อยลงเมื่อเปลี่ยนโครงสร้างพื้นฐาน

ปุ่ม

เริ่มต้น: ติดตั้ง NitroJs ใน 5 นาที

ขั้นตอนที่ 1: สร้างโครงสร้างโปรเจกต์

# ใช้ pnpm (แนะนำ)
pnpm dlx giget@latest nitro nitro-api-backend

# หรือ npm
npm create nitro@latest nitro-api-backend

# หรือ bun
bunx giget@latest nitro nitro-api-backend

นี่เป็นการโคลนเทมเพลตเริ่มต้นอย่างเป็นทางการไปยัง nitro-api-backend

ขั้นตอนที่ 2: สำรวจโครงสร้าง

cd nitro-api-backend
tree -L 2

ผลลัพธ์:

├── server
│   ├── api
│   ├── routes
│   ├── tasks
│   └── middleware
├── nitro.config.ts
├── package.json
└── tsconfig.json

ไดเรกทอรีที่สำคัญ:

สำหรับ API แบ็กเอนด์ล้วนๆ ให้ละเว้น routes และใส่ทุกอย่างไว้ใน api

ขั้นตอนที่ 3: รันเซิร์ฟเวอร์สำหรับพัฒนา

pnpm install
pnpm dev

Nitro จะเริ่มทำงานที่ http://localhost:3000 พร้อม hot reload เมื่อแก้ไขไฟล์ เซิร์ฟเวอร์จะรีสตาร์ทในเวลาไม่ถึง 200ms

เริ่มต้นใช้งาน NitroJs

การสร้าง API Endpoint แรกของคุณ

แฮนเดอร์ GET แบบง่าย

สร้าง server/api/users.get.ts:

// server/api/users.get.ts
export default defineEventHandler(() => {
  return [
    { id: 1, name: "Alice", email: "alice@example.com" },
    { id: 2, name: "Bob", email: "bob@example.com" }
  ];
});

Nitro จะให้บริการนี้ที่ GET /api/users โดยอัตโนมัติ ตัว wrapper defineEventHandler ช่วยให้มั่นใจเรื่องความปลอดภัยของประเภทข้อมูลและสามารถเข้าถึง context ของคำขอได้

เส้นทางไดนามิกพร้อมพารามิเตอร์

สร้าง server/api/users/[id].get.ts:

// server/api/users/[id].get.ts
export default defineEventHandler((event) => {
  const id = getRouterParam(event, 'id');
  
  if (!id) {
    throw createError({
      statusCode: 400,
      statusMessage: 'User ID is required'
    });
  }
  
  return {
    id: Number(id),
    name: `User ${id}`,
    email: `user${id}@example.com`
  };
});

เข้าถึง GET /api/users/42 เพื่อดู { id: 42, name: "User 42", ... }

POST พร้อม JSON Body

สร้าง server/api/users.post.ts:

// server/api/users.post.ts
export default defineEventHandler(async (event) => {
  const body = await readBody(event);
  
  // Nitro แยกวิเคราะห์ JSON โดยอัตโนมัติ
  const { name, email } = body;
  
  if (!name || !email) {
    throw createError({
      statusCode: 422,
      statusMessage: 'Name and email are required'
    });
  }
  
  // จำลองการแทรกข้อมูลลงในฐานข้อมูล
  const newUser = {
    id: Math.floor(Math.random() * 1000),
    name,
    email,
    createdAt: new Date().toISOString()
  };
  
  return newUser;
});

ทดสอบโดยใช้:

curl -X POST http://localhost:3000/api/users \
  -H "Content-Type: application/json" \
  -d '{"name":"Charlie","email":"charlie@example.com"}'

การตอบสนองที่ปลอดภัยด้านประเภทข้อมูล (Type-Safe)

Nitro อนุมานประเภทการตอบสนองจากค่าที่ส่งคืนของคุณ สำหรับสัญญาที่เข้มงวด ให้ใช้ประเภทข้อมูลที่ชัดเจน:

// server/api/products.get.ts
interface Product {
  id: number;
  name: string;
  price: number;
  inStock: boolean;
}

export default defineEventHandler<Product[]>(() => {
  return [
    { id: 1, name: "Laptop", price: 1299.99, inStock: true },
    { id: 2, name: "Mouse", price: 29.99, inStock: false }
  ];
});

ตอนนี้ไคลเอ็นต์ที่อิมพอร์ต endpoint นี้จะได้รับ IntelliSense เต็มรูปแบบ

รูปแบบ API ขั้นสูง

มิดเดิลแวร์สำหรับการตรวจสอบสิทธิ์

สร้าง server/middleware/auth.ts:

// server/middleware/auth.ts
export default defineEventHandler(async (event) => {
  const protectedRoutes = ['/api/admin', '/api/users/me'];
  
  if (protectedRoutes.some(route => event.path.startsWith(route))) {
    const token = getHeader(event, 'authorization')?.replace('Bearer ', '');
    
    if (!token || token !== process.env.API_SECRET) {
      throw createError({
        statusCode: 401,
        statusMessage: 'Unauthorized'
      });
    }
  }
});

มิดเดิลแวร์ทำงานก่อนทุกเส้นทาง เพิ่มลงใน nitro.config.ts:

// nitro.config.ts
export default defineNitroConfig({
  srcDir: 'server',
  runtimeConfig: {
    apiSecret: process.env.API_SECRET
  }
});

การแคชการตอบสนอง API

แคชการคำนวณที่ใช้เวลานานเป็นเวลา 60 วินาที:

// server/api/stats.get.ts
export default defineCachedEventHandler(async () => {
  const db = useStorage('data');
  const users = await db.getItem('users') || [];
  
  return {
    totalUsers: users.length,
    activeUsers: users.filter(u => u.lastSeen > Date.now() - 86400000).length
  };
}, {
  maxAge: 60, // วินาที
  name: 'stats',
  getKey: () => 'global-stats'
});

Nitro จัดการการล้างแคชและการจัดเก็บข้อมูล (หน่วยความจำ, Redis หรือ Cloudflare KV ตามเป้าหมายการดีพลอย)

การจัดการการอัปโหลดไฟล์

// server/api/upload.post.ts
export default defineEventHandler(async (event) => {
  const files = await readMultipartFormData(event);
  
  if (!files?.length) {
    throw createError({ statusCode: 400, statusMessage: 'ไม่พบไฟล์ที่อัปโหลด' });
  }
  
  const storage = useStorage('uploads');
  const file = files[0];
  
  await storage.setItem(file.filename, file.data);
  
  return { success: true, filename: file.filename };
});

ทดสอบด้วย:

curl -X POST http://localhost:3000/api/upload \
  -F "file=@/path/to/image.jpg"

การดีพลอย: จาก Local สู่ Production

สร้างสำหรับ Production

pnpm build

Nitro สร้างไดเรกทอรี .output พร้อม entry points เฉพาะแพลตฟอร์ม

รันบน Node.js

node .output/server/index.mjs

ไม่จำเป็นต้องมี node_modules—บิลด์จะรวมทุกอย่างไว้ด้วยกัน

ดีพลอยไปยัง Cloudflare Workers

# ติดตั้ง preset
pnpm add -D nitro-preset-cloudflare-workers

# สร้างด้วย preset
NITRO_PRESET=cloudflare-workers pnpm build

# ดีพลอย
wrangler deploy .output

ดีพลอยไปยัง Vercel (Serverless)

# Vercel ตรวจจับ Nitro โดยอัตโนมัติ
vercel

หรือกำหนดค่า nitro.config.ts:

export default defineNitroConfig({
  preset: 'vercel-edge'
});

ตัวแปรสภาพแวดล้อม

สร้าง .env ในเครื่องของคุณ จากนั้นใช้แดชบอร์ดแพลตฟอร์มในการผลิต:

# .env
API_SECRET=dev-secret-key
DATABASE_URL=file:./dev.db

เข้าถึงได้ในแฮนเดอร์:

const config = useRuntimeConfig();
const secret = config.apiSecret;

กรณีการใช้งานขั้นสูง

WebSockets & Server-Sent Events

Nitro รองรับ WebSockets ผ่าน defineWebSocketHandler:

// server/api/ws.ts
export default defineWebSocketHandler({
  open(peer) {
    console.log('WebSocket เชื่อมต่อแล้ว:', peer);
  },
  message(peer, message) {
    peer.send(`Echo: ${message.text()}`);
  },
  close(peer, details) {
    console.log('WebSocket ปิดแล้ว:', details);
  }
});

เข้าถึงได้ที่ ws://localhost:3000/api/ws

งานเบื้องหลัง

สร้าง server/tasks/cleanup.ts:

// server/tasks/cleanup.ts
export default defineCronHandler('0 2 * * *', async () => {
  const db = useStorage('temp');
  const keys = await db.getKeys();
  
  for (const key of keys) {
    const metadata = await db.getMeta(key);
    if (metadata.expiresAt < Date.now()) {
      await db.removeItem(key);
    }
  }
  
  console.log('การล้างข้อมูลเสร็จสมบูรณ์');
});

สิ่งนี้จะทำงานทุกวันเวลา 02:00 น. ดีพลอยไปยังแพลตฟอร์มที่รองรับ cron (เช่น Vercel, Netlify)

เอนจินเวิร์กโฟลว์

ผสานรวมกับ useWorkflow.dev สำหรับการจัดระบบที่ซับซ้อน:

// server/api/workflows/process.ts
import { createWorkflow } from '@useworkflow/sdk';

export default defineEventHandler(async (event) => {
  const workflow = createWorkflow('data-pipeline', {
    steps: [
      { id: 'fetch', run: 'https://api.example.com/data' },
      { id: 'transform', run: 'transform.js' },
      { id: 'store', run: async (data) => {
        const storage = useStorage('results');
        await storage.setItem('latest', data);
      }}
    ]
  });
  
  await workflow.start();
  return { status: 'เริ่มแล้ว' };
});

สถานการณ์จำลองสำหรับนักพัฒนาจริง

สถานการณ์ที่ 1: แบ็กเอนด์ของ Static Site

ดีพลอย Nitro API ไปยัง Cloudflare Workers ที่ให้บริการข้อมูล JSON แก่เว็บไซต์ JAMstack แบบคงที่ (static) โดย tier ฟรีรองรับ 100K คำขอต่อวัน

สถานการณ์ที่ 2: API สำหรับแอปพลิเคชันมือถือ

สร้าง REST endpoint สำหรับแอป React Native ใช้การจัดการ CORS ในตัวของ Nitro:

// nitro.config.ts
export default defineNitroConfig({
  routeRules: {
    '/api/**': { cors: true }
  }
});

สถานการณ์ที่ 3: Microservices Gateway

รัน Nitro เป็น API gateway ที่รวมไมโครเซอร์วิสต่างๆ ใช้ $fetch เพื่อเป็นพร็อกซีคำขอ:

// server/api/aggregate.get.ts
export default defineEventHandler(async (event) => {
  const [users, posts] = await Promise.all([
    $fetch('https://users-service.internal/users'),
    $fetch('https://posts-service.internal/posts')
  ]);
  
  return { users, posts };
});

ทดสอบ NitroJs API ของคุณด้วย Apidog

Nitro สร้างแบ็กเอนด์ได้อย่างรวดเร็ว แต่ความเร็วก็ไม่มีความหมายหาก endpoint ของคุณเสีย เมื่อคุณส่งมอบ POST /api/users ใหม่ ให้นำนิยามเส้นทางเข้าสู่ Apidog ซึ่งจะทำการ reverse-engineer ประเภทการคืนค่าของแฮนเดอร์ของคุณ และสร้างการทดสอบสัญญาโดยอัตโนมัติ

การทดสอบสัญญา API ด้วย Apidog
ปุ่ม

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

คำถามที่พบบ่อย

1. Nitro สามารถแทนที่ Express.js ได้ทั้งหมดหรือไม่?
ได้ Nitro จัดการการกำหนดเส้นทาง, มิดเดิลแวร์, และการดีพลอยได้ดีกว่า ทำการย้ายโดยการย้ายมิดเดิลแวร์ Express ไปยังปลั๊กอิน Nitro และเส้นทางไปยัง server/api/

2. Nitro จัดการการเชื่อมต่อฐานข้อมูลอย่างไร?
ใช้ปลั๊กอิน Nitro เพื่อเริ่มต้น pools เมื่อเริ่มทำงาน เลเยอร์จัดเก็บข้อมูลจะแยกส่วนการแคชออก แต่สำหรับ SQL คุณต้องนำ ORM ของคุณเอง (Prisma, Drizzle) มาใช้

3. Nitro พร้อมสำหรับการใช้งานจริงแล้วหรือยัง?
แน่นอน Nuxt ใช้ Nitro สำหรับเว็บไซต์ production หลายล้านแห่ง มันถูกทดสอบแล้วสำหรับการใช้งานในขนาดใหญ่

4. ฉันสามารถใช้ Nitro กับ GraphQL ได้หรือไม่?
ได้ เพิ่ม GraphQL handler ใน server/api/graphql.post.ts ใช้ไลบรารี Node GraphQL ใดก็ได้—Nitro ไม่ได้จำกัดคุณ

5. ความแตกต่างระหว่าง Nitro กับ Hono คืออะไร?
Hono เป็นเราเตอร์น้ำหนักเบา ส่วน Nitro เป็นชุดเครื่องมือเซิร์ฟเวอร์ที่สมบูรณ์พร้อมบิลด์, presets และพื้นที่จัดเก็บข้อมูล ใช้ Hono สำหรับไมโครเซอร์วิส ใช้ Nitro สำหรับแบ็กเอนด์แบบเต็มรูปแบบ

สรุป

NitroJs ได้ปฏิวัติการพัฒนาแบ็กเอนด์โดยการคอมไพล์ API ของคุณให้เป็น build artifact ที่พกพาได้ คุณจะได้รับการกำหนดเส้นทางตามระบบไฟล์, ความปลอดภัยของ TypeScript, และการดีพลอยแบบสากลโดยไม่มีโค้ดเริ่มต้น สร้าง REST API ถัดไปของคุณด้วย Nitro และตรวจสอบความถูกต้องด้วย Apidog อนาคตของคุณจะขอบคุณเมื่อคุณย้ายจาก Node ไปยัง edge ได้ด้วยการกำหนดค่าเพียงบรรทัดเดียว

ปุ่ม

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API