Công cụ AI Coding

Dùng Claude Code build REST API backend: hướng dẫn từng bước (2026)

Aug 14, 202615 phút đọc

Để build REST API backend bằng Claude Code, bạn đi qua 7 bước: lập kế hoạch endpoint & schema, khởi tạo dự án và data layer, viết CRUD từng resource, thêm auth/validation, test, bảo mật production, rồi deploy. Claude Code lo phần boilerplate (scaffold, model, migration, test), còn bạn giữ vai trò review auth và bảo mật. Một API CRUD cơ bản mất khoảng 30-60 phút. Bài này build một API "tasks" chạy thật với Express + Prisma + PostgreSQL, kèm code chạy được và response JSON thật.

tác giả: Jasmine, dev ship backend bằng Claude Code hằng ngày.

Vì sao dùng Claude Code để build REST API backend?

Claude Code là một agentic CLI: nó đọc được cả repo, sinh nhiều file cùng lúc, rồi tự chạy lệnh và test để kiểm tra kết quả (theo tài liệu chính thức của Anthropic, cập nhật 2026). Đúng đặc điểm này khiến nó hợp với backend hơn là một chatbot dán code: một REST API thực chất là rất nhiều boilerplate lặp lại - model, migration, controller CRUD, validation, test, docs. Đây là loại việc tốn thời gian nhưng ít sáng tạo, và là chỗ AI tăng tốc rõ nhất.

Cái được lớn nhất là tốc độ scaffold: thay vì gõ tay 6 endpoint giống nhau, bạn mô tả resource một lần, Claude Code sinh cả tầng data lẫn tầng REST rồi chạy thử. Nó cũng giỏi việc "buồn tẻ" như viết Zod/Pydantic schema khớp với model, hay dựng bộ test cho từng route.

Nhưng phải nói thẳng cái phải giữ: bạn vẫn là người review. Claude Code không hiểu ngữ cảnh bảo mật của bạn - nó hay để default lỏng (thiếu authz trên route, secret nằm trong code, validation cho có). Với logic tiền bạc hay phân quyền, phần AI sinh ra chỉ là bản nháp đầu tiên. Nếu bạn còn mới, đọc trước Claude Code là gì để nắm cách nó vận hành trước khi giao việc backend.

Chuẩn bị trước khi bắt đầu

Checklist trước khi mở Claude Code - chuẩn bị đủ để cả phiên làm việc trôi chảy:

  • Claude Code đã cài và chạy được trong terminal - xem hướng dẫn cài đặt Claude Code nếu chưa.
  • Runtime: Node 20+ (cho Express) hoặc Python 3.11+ (cho FastAPI).
  • Database: PostgreSQL (bản production) hoặc SQLite (dev nhanh, không cần server).
  • Git repo đã git init - để review diff từng bước và revert khi cần.
  • Một file CLAUDE.md khai quy ước dự án - đây là thứ tạo khác biệt lớn nhất giữa output tốt và output lộn xộn.

File CLAUDE.md đặt ở gốc repo, Claude Code tự đọc mỗi phiên. Với backend, khai rõ quy ước layer, validation và error shape ngay từ đầu để đỡ phải nhắc lại:

# CLAUDE.md - quy ước backend

## Kiến trúc
- Tách 3 tầng: routes → controllers → services. Không truy vấn DB trong controller.
- ORM: Prisma. Mọi truy vấn qua service, không viết SQL thô trừ khi bắt buộc.

## Validation & lỗi
- Validate input bằng Zod ở đầu mỗi handler.
- Lỗi trả JSON: { "error": { "code": string, "message": string } }
- Status code: 200/201 thành công, 400 validate lỗi, 401 chưa auth,
 403 không đủ quyền, 404 not found, 500 lỗi server.

## Bảo mật (BẮT BUỘC, không tự ý bỏ)
- KHÔNG hardcode secret. Đọc từ process.env.
- Mọi route ghi/sửa/xoá phải qua middleware auth.
- Không trả field nhạy cảm (passwordHash) trong response.

## Test
- Mỗi endpoint có ít nhất 1 test happy-path + 1 test lỗi (Jest + Supertest).

Chỉ với file này, chất lượng code Claude Code sinh ra đã nhảy một bậc - vì nó có "hợp đồng" để bám vào thay vì đoán phong cách của bạn.

Chọn stack - Node/Express hay Python/FastAPI?

Không có stack "đúng" tuyệt đối, nhưng có stack hợp với cách Claude Code làm việc. Bảng so sánh nhanh 4 lựa chọn phổ biến:

StackTốc độ scaffoldType-safetyHệ sinh tháiĐộ hợp với Claude Code
Express + PrismaRất nhanhKhá (qua TS + Prisma)Rất lớn (JS)Cao - nhiều pattern quen thuộc
FastAPI + SQLAlchemyNhanhCao (Pydantic type-hint)Lớn (Python)Rất cao - type-hint giúp AI ít ảo giác
NestJSTrung bìnhRất caoLớnTrung bình - nhiều boilerplate, decorator
Django RESTTrung bìnhTrung bìnhRất lớn (Python)Khá - quy ước chặt, ít linh hoạt

Cho cả bài này mình chốt Express + Prisma + PostgreSQL: JS-first, phổ biến ở VN, và Prisma cho type-safety đủ dùng mà không nặng như NestJS. Nếu team bạn theo Python, FastAPI + SQLAlchemy cũng tuyệt vời - thậm chí type-hint của Pydantic giúp Claude Code ít sinh code sai kiểu hơn. Điểm quan trọng: chốt một stack và bám suốt bài, đừng để Claude Code "tự chọn" giữa chừng - đó là công thức tạo ra dự án lai tạp khó bảo trì.

Bước 1 - Lập kế hoạch endpoints & schema với Claude Code

Đừng bảo Claude Code "build cho tôi cái API" rồi để nó code luôn. Bắt đầu bằng lập kế hoạch: cho nó brainstorm resource, endpoint và schema DB trước, để bạn duyệt thiết kế trước khi có dòng code nào. Prompt mẫu copy-paste:

Mình muốn build REST API quản lý "tasks" với Express + Prisma + PostgreSQL.
Trước khi code, hãy đề xuất:
1. Danh sách endpoint (method + path + mô tả) cho CRUD tasks.
2. Schema bảng Task (field, kiểu, ràng buộc).
3. Response shape mẫu cho mỗi endpoint.
Trình bày dạng bảng. CHƯA code, mình sẽ duyệt trước.

Claude Code sẽ trả một bảng endpoint kiểu này để bạn chốt:

MethodPathMô tả
GET/tasksLiệt kê task (hỗ trợ phân trang)
GET/tasks/:idLấy 1 task
POST/tasksTạo task mới
PATCH/tasks/:idCập nhật một phần
DELETE/tasks/:idXoá task

Duyệt kỹ ở bước này: field có đủ chưa, có cần status enum không, phân trang theo cursor hay offset. Sửa thiết kế bằng lời rẻ hơn nhiều so với sửa code đã sinh. Đây cũng là chỗ áp dụng tư duy lập kế hoạch trước khi code với Claude Code.

Bước 2 - Khởi tạo dự án & data layer

Chốt thiết kế xong, giờ mới cho Claude Code scaffold. Prompt:

Khởi tạo dự án Express + TypeScript theo kế hoạch vừa duyệt:
- Cài express, prisma, @prisma/client, zod, dotenv.
- Tạo schema Prisma cho model Task như thiết kế.
- Sinh migration đầu tiên và file seed 3 task mẫu.
- Cấu trúc thư mục: src/routes, src/controllers, src/services, src/lib.
Sau khi tạo, DỪNG lại cho mình đọc migration trước khi chạy.

Kết quả schema Prisma nên trông như thế này:

// prisma/schema.prisma
model Task {
 id String @id @default(uuid())
 title String
 detail String?
 status Status @default(TODO)
 createdAt DateTime @default(now())
 updatedAt DateTime @updatedAt
}

enum Status {
 TODO
 DOING
 DONE
}

Đọc lại migration trước khi chạy - đây không phải lời khuyên cho có. Claude Code đôi khi thêm cột thừa, đặt default sai, hay bỏ index cần thiết. Chạy npx prisma migrate dev --name init chỉ khi bạn đã hiểu diff. Nếu muốn đào sâu phần này, xem bài dùng Claude Code với database.

Bước 3 - Build endpoints CRUD từng resource

Nguyên tắc vàng: từng endpoint một, không "build hết một lần". Khi bạn bảo Claude Code làm 5 route cùng lúc, nó dễ trôi và bạn khó review. Làm từng cái, review, commit, rồi sang cái tiếp theo. Bắt đầu với POST và GET:

// src/controllers/task.controller.ts
import { Request, Response } from "express";
import { z } from "zod";
import * as taskService from "../services/task.service";

const createSchema = z.object({
 title: z.string().min(1).max(200),
 detail: z.string().max(2000).optional(),
 status: z.enum(["TODO", "DOING", "DONE"]).optional(),
});

export async function createTask(req: Request, res: Response) {
 const parsed = createSchema.safeParse(req.body);
 if (!parsed.success) {
 return res.status(400).json({
 error: { code: "VALIDATION_ERROR", message: parsed.error.message },
 });
 }
 const task = await taskService.create(parsed.data);
 return res.status(201).json(task);
}

export async function listTasks(req: Request, res: Response) {
 const tasks = await taskService.findAll();
 return res.status(200).json(tasks);
}

Chú ý hai thứ khi review: response shape có khớp CLAUDE.md không (error object đúng dạng chưa), và status code có đúng ngữ nghĩa không (201 cho tạo mới, không phải 200). Đây là chỗ Claude Code hay ẩu - thường trả 200 cho mọi thứ nếu bạn không khai rõ.

Claude Code dùng skills để chuẩn hoá những pattern này, nên nếu bạn có skill backend riêng, output sẽ nhất quán hơn nhiều so với prompt trần.

Bước 4 - Auth & validation (JWT hoặc API key)

Hầu hết tutorial dừng ở "add JWT if required". Không đủ. Đây là middleware JWT thật, bảo vệ các route ghi/sửa/xoá:

// src/lib/auth.ts
import { Request, Response, NextFunction } from "express";
import jwt from "jsonwebtoken";

export function requireAuth(req: Request, res: Response, next: NextFunction) {
 const header = req.headers.authorization;
 if (!header?.startsWith("Bearer ")) {
 return res.status(401).json({
 error: { code: "UNAUTHORIZED", message: "Thiếu token" },
 });
 }
 try {
 const payload = jwt.verify(header.slice(7), process.env.JWT_SECRET!);
 (req as any).user = payload;
 next();
 } catch {
 return res.status(401).json({
 error: { code: "INVALID_TOKEN", message: "Token không hợp lệ" },
 });
 }
}

Gắn vào route ghi: router.post("/tasks", requireAuth, createTask). Với API nội bộ đơn giản, một API key so khớp hằng số cũng đủ - nhưng luôn so khớp bằng hàm timing-safe, đừng dùng === trần.

⚠️ Bắt buộc review tay: Claude Code thường để default kém an toàn - quên gắn requireAuth lên đúng route, để JWT_SECRET fallback thành chuỗi cứng trong code, hoặc bỏ qua kiểm tra quyền sở hữu (user A sửa được task của user B). Sau khi AI sinh xong middleware, tự tay soát lại: mọi route nhạy cảm đã có auth chưa, secret đọc từ env chưa, và authz (không chỉ authn) đã đúng chưa.

Bước 5 - Test API (kết hợp TDD với AI)

Claude Code không chỉ viết test, nó còn tự chạy test và curl để verify - đây là ưu thế agentic thật sự. Prompt: "Viết test Jest + Supertest cho POST /tasks và GET /tasks, gồm happy-path và case validate lỗi, rồi chạy thử." Một test mẫu:

// tests/task.test.ts
import request from "supertest";
import app from "../src/app";

describe("POST /tasks", () => {
 it("tạo task hợp lệ trả 201", async () => {
 const res = await request(app)
 .post("/tasks")
 .set("Authorization", `Bearer ${process.env.TEST_TOKEN}`)
 .send({ title: "Viết bài F1" });
 expect(res.status).toBe(201);
 expect(res.body.title).toBe("Viết bài F1");
 });

 it("thiếu title trả 400", async () => {
 const res = await request(app)
 .post("/tasks")
 .set("Authorization", `Bearer ${process.env.TEST_TOKEN}`)
 .send({});
 expect(res.status).toBe(400);
 });
});

Verify thủ công bằng curl để thấy response JSON thật:

$ curl -s -X POST http://localhost:3000/tasks \
 -H "Authorization: Bearer $TOKEN" \
 -H "Content-Type: application/json" \
 -d '{"title":"Viết bài F1","status":"DOING"}'

{
 "id": "a3f1c9e2-...-8b71",
 "title": "Viết bài F1",
 "detail": null,
 "status": "DOING",
 "createdAt": "2026-08-09T04:12:30.882Z",
 "updatedAt": "2026-08-09T04:12:30.882Z"
}

Để Claude Code viết test trước khi implement là cách áp dụng TDD với AI hiệu quả: test đóng vai "hợp đồng", AI code cho đến khi test xanh.

Bước 6 - Bảo mật & xử lý lỗi production

Đây là phần đối thủ gần như bỏ trắng. Trước khi đưa API ra internet, bảo Claude Code thêm các lớp sau - nhưng tự bạn duyệt checklist:

  • Rate limit: express-rate-limit, chặn brute-force và abuse (ví dụ 100 req/phút/IP).
  • CORS: khai whitelist origin cụ thể, đừng để origin: "*" trên API có auth.
  • Env/secrets: mọi khoá qua .env, thêm .env vào .gitignore, dùng .env.example làm mẫu.
  • Input validation: đã có Zod ở mỗi handler - không tin dữ liệu client.
  • Error handler tập trung: một middleware cuối cùng bắt mọi lỗi, không rò stack trace ra response production.
  • Helmet: set các security header HTTP cơ bản.

Checklist OWASP ngắn để soát: có injection không (Prisma đã chống SQLi qua parameterized query), có broken access control không (kiểm authz từng route), có expose dữ liệu nhạy cảm không (đừng trả field thừa). Muốn Claude Code tự rà lỗ hổng, xem cách chạy security audit bằng Claude Code.

Bước 7 - Deploy API lên URL thật

Mình dùng Railway cho demo vì nó nhận Postgres kèm sẵn và deploy từ Git chỉ vài phút. Các bước:

  1. Push repo lên GitHub.
  2. Trên Railway, tạo project từ repo, add một PostgreSQL service - nó tự tạo DATABASE_URL.
  3. Khai biến môi trường production: JWT_SECRET, DATABASE_URL, NODE_ENV=production.
  4. Đặt build command npx prisma migrate deploy && npm run build và start command npm start.

Nếu muốn portable hơn (chạy được cả trên Render, Fly.io, VPS), thêm Dockerfile tối giản:

# Dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npx prisma generate && npm run build
EXPOSE 3000
CMD ["npm", "start"]

Sau khi deploy, gọi thử endpoint qua URL live để chắc chắn migration đã chạy và env đúng. Chi tiết từng nền tảng có ở bài deploy app bằng Claude Code.

Làm nhanh hơn: AgentKit ship sẵn skill ak-backend-development

Một dòng phân biệt cho khỏi nhầm: AgentKit ở đây là bộ kit cho Claude Code (agentkit.best, CLI ak) - không phải OpenAI AgentKit (Agent Builder/ChatKit, ra mắt 06/10/2025). Hai thứ trùng tên nhưng khác hẳn.

Toàn bộ 7 bước trên đòi bạn tự khai quy ước trong CLAUDE.md và nhắc lại pattern mỗi phiên. AgentKit cho Claude Code (giảm 20% qua link) đóng gói sẵn skill ak-backend-development theo trang giới thiệu: hỗ trợ Node/Python/Go (NestJS, FastAPI, Django), auth OAuth/JWT, checklist bảo mật OWASP, và Docker/K8s. Nghĩa là Claude Code làm đúng 7 bước này theo quy ước chuẩn sẵn, bạn đỡ phải dựng lại "hợp đồng" từ đầu mỗi dự án.

Trung thực: kit không bắt buộc - làm tay hoàn toàn được, và bài này đã chứng minh điều đó. Kit chỉ tiết kiệm công thiết lập nếu bạn build backend thường xuyên. Engineer Kit giá $99 (trang không nêu phí định kỳ), kèm "money-back guarantee" và "lifetime updates". Xem Engineer Kit của AgentKit có gì để cân nhắc trước khi mua.

Giới hạn thật & khi nào phải review tay

Đây là phần zero đối thủ nào có, và cũng là phần quan trọng nhất. Sau nhiều dự án backend với Claude Code, đây là các failure mode lặp lại mà mình luôn phải soát:

  • Import/ORM sai: gọi hàm Prisma không tồn tại, hoặc import sai package version - code trông đúng nhưng chạy là lỗi.
  • Thiếu authz trên route: có auth (biết bạn là ai) nhưng thiếu authz (bạn có quyền không) - user sửa được dữ liệu của người khác.
  • Validation lỏng: validate title nhưng quên giới hạn độ dài, quên sanitize, để lọt kiểu dữ liệu lạ.
  • N+1 query: vòng lặp gọi DB từng item thay vì một truy vấn - chạy tốt ở dev, sập ở production.
  • Secret hardcode: để JWT_SECRET hoặc connection string thẳng trong code làm fallback.
  • "Trông chạy" nhưng sai business logic: code compile, test happy-path xanh, nhưng logic tính toán/trạng thái sai - chỉ người hiểu domain mới bắt được.

Quy tắc mình dùng: Claude Code cho boilerplate, con người review cho auth, bảo mật và logic tiền bạc. AI sinh 80% khối lượng nhanh gấp nhiều lần; 20% còn lại - đúng phần rủi ro cao - là nơi bạn không được khoán trắng. Đó không phải điểm yếu của công cụ, mà là cách dùng đúng.

Câu hỏi thường gặp (FAQ)

Claude Code build backend production-ready chưa?

Chưa hoàn toàn tự động. Claude Code sinh được code chạy thật và có cấu trúc tốt, nhưng phần auth, phân quyền, bảo mật và business logic cần người review kỹ trước khi lên production. Coi output là bản nháp đầu tiên chất lượng cao, không phải bản cuối.

Cần biết code không hay người mới cũng làm được?

Bạn cần biết đọc code và hiểu cơ bản về HTTP/REST, database để review được output. Người mới vẫn build được API chạy, nhưng sẽ khó phát hiện lỗi bảo mật hay logic mà Claude Code sinh ra - nên hãy học song song, đừng khoán trắng.

Build GraphQL hay gRPC được không?

Được. Bài này demo REST vì phổ biến nhất, nhưng Claude Code build được cả GraphQL (Apollo) và gRPC. Nguyên tắc y hệt: lập kế hoạch schema trước, build từng phần, và tự review phần auth/bảo mật.

Stack nào hợp Claude Code nhất?

Express + Prisma (JS) và FastAPI + SQLAlchemy (Python) là hai lựa chọn hợp nhất - nhiều pattern quen thuộc và type-safety đủ để AI ít ảo giác. FastAPI nhỉnh hơn ở khoản type-hint giúp giảm lỗi sai kiểu.

Code Claude Code sinh ra có an toàn không?

Không mặc định an toàn. Claude Code hay để default lỏng: thiếu authz, secret trong code, validation sơ sài. Bạn phải tự soát checklist bảo mật (rate limit, CORS, env, OWASP) và review từng route nhạy cảm trước khi deploy.

Build một API CRUD cơ bản mất bao lâu?

Khoảng 30-60 phút cho một REST API CRUD hoàn chỉnh với auth và test cơ bản, tính cả thời gian review. Phần scaffold và boilerplate nhanh; thời gian thật nằm ở review auth, bảo mật và chỉnh business logic.

Kết luận & bước tiếp theo

Tóm lại 7 bước: lập kế hoạch endpoint & schema → khởi tạo dự án và data layer → build CRUD từng resource → thêm auth/validation → test → bảo mật production → deploy. Claude Code lo phần boilerplate, bạn giữ vai trò review auth và logic - đó là cách chia việc đúng. Bước tiếp theo nên đào sâu: viết test & TDD với AI để API vững hơn, và deploy app bằng Claude Code để đưa nó ra URL thật.

Muốn Claude Code build backend nhanh hơn? Nếu bạn dựng API thường xuyên, bộ kit backend dựng sẵn ak-backend-development giúp Claude Code theo đúng quy ước chuẩn mà không phải khai lại mỗi lần. Không bắt buộc - làm tay vẫn được.

Xem AgentKit (giảm 20% qua link) →

J

Jasmine

Tác giả · Jasmine Daily

Người viết nên Jasmine Daily - ghi lại những suy nghĩ, trải nghiệm và những khoảnh khắc đời thường. Thật lòng, không vội vàng, không hoàn hảo.

Jasmine Daily

Vẫn còn nhiều điều đang chờ được đọc.

Nếu bài viết này chạm đến bạn, hãy ghé xem thêm vài trang khác trong cuốn nhật ký này.

Đọc tiếp

Bài viết liên quan