Kết nối thế giới bên ngoài — API & MCP
Mục tiêu
Hiểu API là gì và cách dùng. Biết MCP (Model Context Protocol) — xu hướng mới nhất cho phép AI kết nối trực tiếp với công cụ bên ngoài.
Sau bài này, bạn sẽ:
- ✅ Hiểu API hoạt động như thế nào và tại sao cần tích hợp API bên ngoài
- ✅ Biết cách prompt AI để tích hợp API vào app một cách an toàn
- ✅ Hiểu MCP là gì và cách setup MCP server trong Cursor
- ✅ Xử lý được các lỗi phổ biến khi gọi API (401, 403, 500…)
Nội dung chính
3.1 — API: “Bồi bàn giữa các nhà hàng”
Ở Course 2, API là bồi bàn trong 1 nhà hàng (giữa Frontend và Backend của bạn). Giờ mở rộng: API cũng là bồi bàn giữa các nhà hàng khác nhau.
APP CỦA BẠN API DỊCH VỤ BÊN NGOÀI
───────────── ───── ──────────────────
"Thời tiết TP.HCM ─────▶ OpenWeatherMap
hôm nay thế nào?" ◀───── → Trả: 32°C, mưa chiều
"Tạo hình ảnh con ─────▶ DALL-E API
mèo đang uống trà" ◀───── → Trả: URL hình ảnh
"Gửi email xác nhận ─────▶ SendGrid API
cho user@gmail.com" ◀───── → Trả: "Đã gửi thành công"
Mẹo: API key giống như chìa khoá vào nhà hàng VIP. Mỗi dịch vụ cấp cho bạn 1 key riêng. Key này phải giữ bí mật (trong file .env), nếu lộ ra thì người khác dùng key của bạn → bạn bị tính phí.
3.2 — Cách tích hợp API qua AI
Bạn không cần tự viết code gọi API. Prompt AI:
Tích hợp API thời tiết từ OpenWeatherMap vào app của tôi.
Thông tin API:
- Đăng ký API key miễn phí tại: https://openweathermap.org/api
- Endpoint: https://api.openweathermap.org/data/2.5/weather
- Params: q={city}&appid={key}&units=metric&lang=vi
Yêu cầu chi tiết:
1. Tạo file lib/weather.js chứa function gọi API
2. API key lưu trong .env (biến VITE_WEATHER_API_KEY)
3. Hiển thị: nhiệt độ (°C), tình trạng (nắng/mưa/mây), icon thời tiết
4. Cho phép user tìm kiếm theo tên thành phố (input + nút search)
5. Hiển thị loading spinner khi đang gọi API
6. Hiển thị thông báo lỗi nếu:
- Thành phố không tồn tại → "Không tìm thấy thành phố này"
- Mất internet → "Kiểm tra kết nối mạng"
- API key sai → "Lỗi xác thực, kiểm tra API key"
7. Cache kết quả 5 phút (không gọi API lại nếu user tìm cùng thành phố)
8. Default hiển thị thời tiết Hồ Chí Minh khi mở app
Dùng fetch() hoặc axios, tuỳ cái nào đã có trong project.
Prompt nâng cao — Tích hợp nhiều API cùng lúc:
Tôi cần tích hợp 2 API vào app FocusFlow:
API 1 - Quotes (câu nói truyền cảm hứng):
- Endpoint: https://api.quotable.io/random
- Không cần API key
- Hiển thị 1 câu quote ngẫu nhiên mỗi khi bắt đầu Pomodoro session
- Hiển thị tên tác giả bên dưới
API 2 - Spotify (nhạc nền):
- Dùng Spotify Web API
- Hiển thị danh sách playlist "Focus" có sẵn
- Cho user bấm play → mở Spotify app/web
Yêu cầu chung:
- Mỗi API tạo 1 file riêng trong lib/
- Error handling cho cả 2
- Không block UI nếu 1 API bị lỗi (app vẫn chạy bình thường)
Các API miễn phí phổ biến để thực hành:
| API | Cung cấp | Dùng cho |
|---|---|---|
| OpenWeatherMap | Thời tiết | App thời tiết |
| NewsAPI | Tin tức | App đọc tin |
| PokeAPI | Dữ liệu Pokemon | App tra cứu vui |
| RestCountries | Thông tin quốc gia | App giáo dục |
| JSONPlaceholder | Dữ liệu giả | Test/học tập |
| Quotable | Câu nói hay | App motivation |
| ExchangeRate API | Tỷ giá tiền tệ | App tài chính |
Mẹo: Bắt đầu với API không cần key (PokeAPI, RestCountries, JSONPlaceholder) để tập trước. Khi đã quen flow gọi API rồi, mới thử API cần key (OpenWeatherMap, NewsAPI).
3.3 — MCP: Model Context Protocol — “Siêu kết nối”
MCP là gì? MCP là giao thức cho phép AI kết nối trực tiếp với các công cụ và dịch vụ bên ngoài — không cần bạn viết code gọi API thủ công.
TRƯỚC MCP: VỚI MCP:
────────── ────────
Bạn: "Lấy data từ Google Sheets" Bạn: "Lấy data từ Google Sheets"
AI: "Đây là code gọi API... bạn AI: *Tự kết nối Google Sheets*
cần cài thư viện này..." *Tự đọc dữ liệu*
Bạn: Copy code → chạy → debug *Trả kết quả ngay*
→ Nhiều bước, dễ lỗi → 1 bước, AI tự xử lý
Ví dụ MCP thực tế:
| MCP Server | Kết nối với | Bạn có thể nói |
|---|---|---|
| Google Sheets | Bảng tính Google | ”Đọc dữ liệu từ sheet Doanh Thu Q1” |
| Slack | Tin nhắn Slack | ”Gửi thông báo deploy lên channel #dev” |
| GitHub | Repository | ”Tạo issue mới cho bug XYZ” |
| Supabase | Database | ”Thêm 10 sản phẩm mẫu vào bảng products” |
| Brave Search | Tìm kiếm web | ”Tìm thông tin mới nhất về React 19” |
3.4 — Setup MCP trong Cursor (chi tiết từng bước)
Bước 1: Mở Cursor Settings → MCP → Add Server
Bước 2: Chọn loại server và cấu hình. Ví dụ thêm Supabase MCP:
{
"mcpServers": {
"supabase": {
"command": "npx",
"args": ["-y", "@supabase/mcp-server"],
"env": {
"SUPABASE_URL": "https://xxxxx.supabase.co",
"SUPABASE_SERVICE_KEY": "eyJxxxxxxx"
}
}
}
}
Bước 3: Kiểm tra MCP đã kết nối — trong Cursor chat, gõ: “Liệt kê tất cả bảng trong database Supabase”. Nếu AI trả lời đúng → MCP hoạt động.
Bước 4: Sử dụng MCP trong workflow hàng ngày:
Ví dụ các câu lệnh khi đã có Supabase MCP:
"Thêm 10 sản phẩm mẫu vào bảng products"
"Tạo bảng mới tên orders với cột: id, user_id, total, status"
"Bật RLS cho bảng users, chỉ cho phép user xem data của mình"
"Backup data từ bảng sessions ra file JSON"
Sau khi setup, AI trong Cursor có thể trực tiếp đọc/ghi database mà không cần bạn viết code kết nối.
Mẹo: MCP rất tiện nhưng hãy cẩn thận với quyền truy cập. Dùng Supabase MCP với
service_keycó toàn quyền — nghĩa là AI có thể xóa data. Trong project thật, tạo key riêng với quyền hạn chế (chỉ đọc, hoặc chỉ truy cập 1 vài bảng).
Lỗi thường gặp
Vấn đề: API trả lỗi 401 Unauthorized — “Invalid API key”.
→ Giải pháp: Kiểm tra 3 thứ: (1) API key trong .env có đúng không? Copy lại từ trang web API. (2) Biến môi trường có prefix đúng không? Vite cần VITE_, Next.js cần NEXT_PUBLIC_. (3) Đã restart npm run dev chưa? Thay đổi .env cần restart server.
Vấn đề: API trả lỗi 429 Too Many Requests — “Rate limit exceeded”. → Giải pháp: Bạn gọi API quá nhiều lần trong thời gian ngắn. Thêm cache (lưu kết quả tạm) hoặc debounce (chờ user ngừng gõ 500ms mới gọi). Prompt AI: “Thêm caching 5 phút và debounce 500ms cho API call.”
Vấn đề: MCP không kết nối — “Server failed to start”.
→ Giải pháp: (1) Kiểm tra đã cài Node.js phiên bản 18+ chưa. (2) Chạy thử command trong terminal trước: npx -y @supabase/mcp-server — xem có lỗi gì không. (3) Kiểm tra SUPABASE_URL và SUPABASE_SERVICE_KEY có đúng không. (4) Restart Cursor hoàn toàn (Quit → mở lại).
Vấn đề: API trả data nhưng app không hiển thị. → Giải pháp: Thường là do cấu trúc JSON không khớp với code. Prompt AI: “Console.log dữ liệu trả về từ API và cho tôi xem cấu trúc JSON. Sau đó sửa code để hiển thị đúng theo cấu trúc đó.”
Vấn đề: CORS error — “Access-Control-Allow-Origin” khi gọi API từ trình duyệt. → Giải pháp: Một số API không cho phép gọi trực tiếp từ trình duyệt. Prompt AI: “Tạo proxy endpoint đơn giản để gọi API [tên] qua server-side, tránh CORS.”
Bài tập thực hành
Nhiệm vụ: Tích hợp 1 API bên ngoài vào đồ án:
Nếu đồ án là API gợi ý FocusFlow Quotes API — hiển thị câu nói truyền cảm hứng mỗi session HabitStack OpenWeatherMap — nhắc “Trời đẹp, đi chạy bộ đi!” FanZone Football-data.org — dữ liệu trận đấu thật Tự chọn Chọn API phù hợp từ danh sách trên Các bước thực hiện:
- Chọn API phù hợp và đăng ký API key nếu cần (~5 phút)
- Test API trước bằng trình duyệt hoặc Postman (~5 phút)
- Prompt AI tích hợp API vào app (~15 phút)
- Kiểm tra error handling: thử tắt wifi, thử sai API key (~5 phút)
- Commit (~2 phút)
Bonus: Setup 1 MCP server trong Cursor (Supabase hoặc GitHub) (~8 phút)
Tiêu chí hoàn thành:
- App hiển thị dữ liệu từ API bên ngoài
- API key nằm trong .env, KHÔNG hard-code trong code
- Có loading state khi đang gọi API
- Có error state khi API lỗi
Gợi ý nếu bị stuck: Bắt đầu với API đơn giản nhất — JSONPlaceholder (không cần key, không cần đăng ký). Endpoint:
https://jsonplaceholder.typicode.com/poststrả về danh sách bài viết. Khi đã gọi thành công 1 API, chuyển sang API thật dễ hơn nhiều.Thời gian: 40 phút Deliverable: App hiển thị dữ liệu từ API bên ngoài + commit
Kiểm tra kiến thức
1. API key nên được lưu ở đâu trong project?
2. MCP (Model Context Protocol) giúp AI làm gì?
3. Lỗi 429 Too Many Requests nghĩa là gì?
4. Khi mới bắt đầu học tích hợp API, nên chọn loại API nào?
5. Khi setup Supabase MCP, cần cẩn thận điều gì?