Prompting to Generate Structured APIs: Hướng Dẫn Thực Chiến từ Người Có 12 Năm Kinh Nghiệm
Chào anh em, mình là Hải – một Senior Solutions Architect với hơn một tá năm chinh chiến trong nghề lập trình và quản lý dự án. Hôm nay mình ngồi viết bài này không phải để khoe khoang hay PR mấy cái dự án lớn, mà đơn giản là muốn chia sẻ một chủ đề đang rất “hot” và thực tế: Prompting to Generate Structured APIs (OpenAPI / GraphQL).
Nghe có vẻ phức tạp, nhưng thực ra nó đơn giản như việc bạn mô tả bằng lời muốn hệ thống làm gì, rồi nó tự sinh ra schema, docs, và cả ví dụ request luôn. Mình gọi đây là “đặc sản” của thời AI, nhưng dùng kiểu gì cho hiệu quả, chuẩn xác và đáng tin cậy thì lại là chuyện khác.
1. Mình Bắt Đầu Từ Đâu? (Hải “Mentor”)
Cách đây vài năm, mỗi lần mình muốn tạo một API mới, quy trình thường là:
- Viết tài liệu mô tả API bằng tay (Swagger/OpenAPI YAML hoặc JSON).
- Code backend.
- Viết lại schema GraphQL nếu dùng GraphQL.
- Test thủ công.
- Viết tài liệu hướng dẫn sử dụng.
Quá trình này tốn thời gian, dễ sai sót, và không scale. Đặc biệt khi team của bạn có 10–20 dev, mỗi người tự viết schema theo cách riêng, thì loạn cả lên.
Rồi AI đến. Ban đầu mình cũng nghi ngờ: “Liệu AI có viết schema chuẩn không? Có hiểu business logic không?”. Nhưng sau vài tháng thử nghiệm, mình nhận ra: nếu prompt đúng, AI có thể làm được rất nhiều việc.
2. Use Case Kỹ Thuật: Khi Hệ Thống Đạt 10.000 User/Giây
Mình từng làm một hệ thống thương mại điện tử cần xử lý 10.000 user đồng thời. Mỗi user đều gọi API để load danh sách sản phẩm, giỏ hàng, thanh toán. Việc viết schema bằng tay là không khả thi vì:
- Mỗi endpoint cần được định nghĩa rõ ràng: method, path, params, body schema, response schema.
- Cần có docs để QA và frontend có thể test nhanh.
- Cần có ví dụ request/response để debug.
Giải pháp: Dùng AI để generate OpenAPI schema từ prompt mô tả business logic.
3. Prompting để Tạo OpenAPI Schema (Hải “Deep Dive”)
3.1. Cấu Trúc Prompt Hiệu Quả
Mình đã thử rất nhiều cách prompt, và đây là cấu trúc mình dùng hiệu quả nhất:
Bạn hãy tạo một OpenAPI 3.0 schema cho API sau:
**Business Context**: Hệ thống quản lý đơn hàng (Order Management System).
**Yêu cầu**:
- API tạo đơn hàng mới (POST /orders)
- API lấy chi tiết đơn hàng (GET /orders/{id})
- API cập nhật trạng thái đơn hàng (PATCH /orders/{id}/status)
**Input**:
- Tạo đơn: { customerId, items: [{productId, quantity, price}], shippingAddress }
- Cập nhật trạng thái: { status: "pending" | "confirmed" | "shipped" | "delivered" | "cancelled" }
**Output**:
- Response chuẩn: { success: boolean, data: {...}, message?: string }
- Error format: { success: false, error: { code, message } }
**Yêu cầu kỹ thuật**:
- Dùng JSON Schema để định nghĩa body và response.
- Có validation: required fields, type checking, enum values.
- Có ví dụ minh họa (examples) cho request và response.
- Có security scheme: API Key trong header (X-API-Key).
Hãy xuất ra file YAML OpenAPI 3.0 đầy đủ.
3.2. Kết Quả Mẫu (OpenAPI 3.0 YAML)
Dưới đây là một ví dụ schema mình đã từng generate thành công:
openapi: 3.0.3
info:
title: Order Management API
description: API quản lý đơn hàng cho hệ thống thương mại điện tử
version: 1.0.0
servers:
- url: https://api.example.com/v1
description: Production server
paths:
/orders:
post:
summary: Tạo đơn hàng mới
security:
- ApiKeyAuth: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateOrderRequest'
examples:
example-1:
summary: Ví dụ tạo đơn hàng
value:
customerId: "user_123"
items:
- productId: "prod_001"
quantity: 2
price: 299000
- productId: "prod_002"
quantity: 1
price: 150000
shippingAddress:
street: "123 Nguyễn Văn Cừ"
city: "Hà Nội"
country: "Vietnam"
zipCode: "100000"
responses:
'201':
description: Tạo đơn hàng thành công
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
examples:
success:
summary: Tạo đơn thành công
value:
success: true
data:
orderId: "order_abc123"
status: "pending"
createdAt: "2025-04-05T10:00:00Z"
'400':
$ref: '#/components/responses/BadRequest'
'401':
$ref: '#/components/responses/Unauthorized'
/orders/{id}:
get:
summary: Lấy chi tiết đơn hàng
security:
- ApiKeyAuth: []
parameters:
- name: id
in: path
required: true
description: ID của đơn hàng
schema:
type: string
example: "order_abc123"
responses:
'200':
description: Lấy thông tin đơn hàng thành công
content:
application/json:
schema:
$ref: '#/components/schemas/Order'
'404':
$ref: '#/components/responses/NotFound'
patch:
summary: Cập nhật trạng thái đơn hàng
security:
- ApiKeyAuth: []
parameters:
- name: id
in: path
required: true
description: ID của đơn hàng
schema:
type: string
example: "order_abc123"
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/UpdateOrderStatusRequest'
examples:
shipped:
summary: Cập nhật trạng thái thành "shipped"
value:
status: "shipped"
responses:
'200':
description: Cập nhật trạng thái thành công
content:
application/json:
schema:
$ref: '#/components/schemas/ApiResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
components:
securitySchemes:
ApiKeyAuth:
type: apiKey
in: header
name: X-API-Key
schemas:
CreateOrderRequest:
type: object
required: ["customerId", "items", "shippingAddress"]
properties:
customerId:
type: string
description: "ID của khách hàng"
example: "user_123"
items:
type: array
minItems: 1
items:
$ref: '#/components/schemas/OrderItem'
shippingAddress:
$ref: '#/components/schemas/Address'
OrderItem:
type: object
required: ["productId", "quantity", "price"]
properties:
productId:
type: string
example: "prod_001"
quantity:
type: integer
minimum: 1
example: 2
price:
type: number
minimum: 0
example: 299000
Address:
type: object
required: ["street", "city", "country", "zipCode"]
properties:
street:
type: string
example: "123 Nguyễn Văn Cừ"
city:
type: string
example: "Hà Nội"
country:
type: string
example: "Vietnam"
zipCode:
type: string
pattern: '^[0-9]{6}$'
example: "100000"
UpdateOrderStatusRequest:
type: object
required: ["status"]
properties:
status:
type: string
enum: ["pending", "confirmed", "shipped", "delivered", "cancelled"]
example: "shipped"
Order:
type: object
properties:
orderId:
type: string
example: "order_abc123"
customerId:
type: string
example: "user_123"
status:
type: string
enum: ["pending", "confirmed", "shipped", "delivered", "cancelled"]
example: "pending"
items:
type: array
items:
$ref: '#/components/schemas/OrderItem'
shippingAddress:
$ref: '#/components/schemas/Address'
createdAt:
type: string
format: date-time
example: "2025-04-05T10:00:00Z"
ApiResponse:
type: object
properties:
success:
type: boolean
example: true
data:
type: object
nullable: true
message:
type: string
nullable: true
example: "Request processed successfully"
responses:
BadRequest:
description: Yêu cầu không hợp lệ
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
invalid_status:
summary: Trạng thái không hợp lệ
value:
success: false
error:
code: "INVALID_STATUS"
message: "Status must be one of: pending, confirmed, shipped, delivered, cancelled"
Unauthorized:
description: Không có quyền truy cập
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
examples:
missing_key:
summary: Thiếu API Key
value:
success: false
error:
code: "UNAUTHORIZED"
message: "Missing or invalid API Key"
NotFound:
description: Không tìm thấy resource
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
Error:
type: object
properties:
success:
type: boolean
example: false
error:
type: object
properties:
code:
type: string
example: "NOT_FOUND"
message:
type: string
example: "Order not found"
Lưu ý: Schema trên có thể validate bằng công cụ như Swagger Editor hoặc Redoc. Mình thường dùng Swagger UI để render docs cho team.
4. Prompting để Tạo GraphQL Schema (Hải “Architect”)
GraphQL thì khác. Nó không cần REST endpoint, mà dùng một schema duy nhất định nghĩa các Type, Query, Mutation.
4.1. Prompt Mẫu
Bạn hãy tạo một GraphQL schema (SDL) cho hệ thống quản lý đơn hàng:
**Types**:
- Order: { id, customerId, status, items, total, createdAt }
- OrderItem: { productId, productName, quantity, price }
- Address: { street, city, country, zipCode }
**Queries**:
- order(id: ID!): Order
- orders(customerId: ID!): [Order!]!
**Mutations**:
- createOrder(input: CreateOrderInput!): Order
- updateOrderStatus(id: ID!, status: OrderStatus!): Order
**Input Types**:
- CreateOrderInput: { customerId, items: [OrderItemInput!]!, shippingAddress: AddressInput! }
- OrderItemInput: { productId, quantity, price }
- AddressInput: { street, city, country, zipCode }
- OrderStatus: enum (pending, confirmed, shipped, delivered, cancelled)
Hãy xuất ra GraphQL SDL (Schema Definition Language) đầy đủ.
4.2. Kết Quả Mẫu (GraphQL SDL)
enum OrderStatus {
pending
confirmed
shipped
delivered
cancelled
}
type Order {
id: ID!
customerId: ID!
status: OrderStatus!
items: [OrderItem!]!
total: Float!
shippingAddress: Address!
createdAt: String!
}
type OrderItem {
productId: ID!
productName: String!
quantity: Int!
price: Float!
}
input OrderItemInput {
productId: ID!
quantity: Int!
price: Float!
}
type Address {
street: String!
city: String!
country: String!
zipCode: String!
}
input AddressInput {
street: String!
city: String!
country: String!
zipCode: String!
}
input CreateOrderInput {
customerId: ID!
items: [OrderItemInput!]!
shippingAddress: AddressInput!
}
type Query {
order(id: ID!): Order
orders(customerId: ID!): [Order!]!
}
type Mutation {
createOrder(input: CreateOrderInput!): Order!
updateOrderStatus(id: ID!, status: OrderStatus!): Order!
}
Tip: Dùng GraphQL Code Generator để tự động sinh TypeScript types từ schema này. Rất tiện cho frontend.
5. So Sánh REST (OpenAPI) vs GraphQL (Hải “Pragmatic”)
| Tiêu chí | OpenAPI (REST) | GraphQL |
|---|---|---|
| Độ khó | Dễ học, phổ biến | Cần hiểu concept (resolver, schema) |
| Hiệu năng | Nhiều request nếu cần nhiều resource | Một request lấy hết (nhưng có thể N+1) |
| Documentation | Swagger UI, Redoc (rất đẹp) | GraphQL Playground, Apollo Studio |
| Type Safety | JSON Schema (tốt) | Strong typing (tốt hơn) |
| Tooling | Rất phong phú (Postman, Insomnia) | Apollo, Relay, Codegen |
| Learning Curve | Dễ | Trung bình |
Kết luận: Nếu team bạn mới, hoặc cần integration với bên thứ 3, dùng OpenAPI. Nếu bạn cần linh hoạt truy vấn và có team frontend mạnh, hãy chọn GraphQL.
6. Lưu Ý Quan Trọng Khi Dùng AI Để Generate Schema (Hải “Security”)
⚠️ Cảnh báo: AI có thể sinh ra schema đẹp, nhưng không có nghĩa là an toàn hoặc tối ưu.
Mình từng gặp trường hợp AI sinh schema có lỗi:
- Thiếu validation: Không có
minLength,pattern, dẫn đến input injection. - Over-expose data: GraphQL trả về field nhạy cảm như
password,internalId. - Không có rate limiting: Schema không định nghĩa limit số lần gọi API.
Best Practice:
- Luôn review schema trước khi deploy.
- Dùng công cụ validate:
swagger-parser,graphql-config. - Test với dữ liệu thực: Dùng Postman/Newman hoặc Jest để test API.
- Không tin 100% vào AI: Dùng AI như trợ lý, không phải thay thế dev.
7. Tích Hợp vào Quy Trình DevOps (Hải “Performance”)
Mình áp dụng quy trình sau:
- Prompt → Generate Schema (bằng AI).
- Validate schema bằng CI/CD (GitHub Actions).
- Generate code stub (bằng OpenAPI Generator hoặc GraphQL Codegen).
- Test automated với schema validation.
- Deploy docs (Swagger UI hoặc GraphQL Studio).
Ví dụ CI/CD Validate OpenAPI:
name: Validate OpenAPI Schema
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Validate OpenAPI
run: |
npm install -g @redocly/openapi-cli
openapi lint openapi.yaml
8. Công Cụ & Tài Liệu Tham Khảo (Hải “Futurist”)
- OpenAPI 3.0 Official Docs: https://swagger.io/specification/
- GraphQL SDL: https://spec.graphql.org/draft/
- Swagger Editor: https://editor.swagger.io/
- GraphQL Code Generator: https://www.graphql-code-generator.com/
- StackOverflow Developer Survey 2024: GraphQL usage tăng 25% so với 2022.
9. Kết Bài: 3 Key Takeaways
- Prompting hiệu quả = Cấu trúc rõ ràng + Ví dụ cụ thể + Yêu cầu kỹ thuật chi tiết.
- AI giúp tiết kiệm thời gian, nhưng không thay thế được review của dev.
- OpenAPI phù hợp với hệ thống lớn, cần integration. GraphQL linh hoạt nhưng cần team có kỹ năng.
10. Thảo Luận
Anh em đã từng dùng AI để generate schema bao giờ chưa? Có ai gặp trường hợp AI sinh ra schema “đẹp nhưng không dùng được” không? Cùng chia sẻ kinh nghiệm nhé!
11. Gợi Ý Công Cụ
Nếu anh em đang làm SEO hoặc content mà muốn tự động hóa quy trình, có thể tham khảo bộ công cụ bên noidungso.io.vn. Mình thấy bên đó có tích hợp AI để viết bài, check đạo văn, và xuất bản tự động – đỡ tốn cơm gạo thuê nhân sự part-time.
Nội dung được Hải định hướng, trợ lý AI giúp mình viết chi tiết.








