TÍCH HỢP BACKEND + API + AI
🎉 TÍCH HỢP BACKEND + API + AI
🚀 Hôm nay, Hướng Nghiệp Dữ Liệu chính thức khai giảng khóa học Flutter Level 3 với chủ đề cực kỳ hấp dẫn: Tích hợp Backend, API và AI trong lập trình Flutter. Đây là cột mốc quan trọng trong lộ trình trở thành Flutter Developer chuyên nghiệp của các bạn học viên.
🕢 THỜI GIAN KHAI GIẢNG:
- ⏰ Thời gian: 07h30, ngày 08/03/2025
- 📅 Lịch học: Thứ 7 và Chủ nhật hàng tuần
💡 VỚI 27 BUỔI HỌC CHUYÊN SÂU, KHÓA HỌC SẼ GIÚP BẠN:
- ✅ Nắm vững cách kết nối Backend (REST API, GraphQL, WebSocket, Firebase).
- ✅ Thành thạo các kỹ năng triển khai Authentication (JWT, OAuth2).
- ✅ Lưu trữ dữ liệu với Firestore, SQLite, Hive.
- ✅ Tích hợp AI (OCR, Face Recognition, Speech to Text, Chatbot AI, Object Detection).
🌐 TÌM HIỂU VỀ REST API:
REST API (Representational State Transfer) là một phong cách kiến trúc được sử dụng rộng rãi trong việc xây dựng các dịch vụ web. REST API hoạt động dựa trên các phương thức HTTP phổ biến như:
- GET: Truy xuất dữ liệu từ server.
- POST: Gửi dữ liệu mới lên server.
- PUT: Cập nhật dữ liệu hiện có.
- DELETE: Xóa dữ liệu.
🔑 Đặc điểm của REST API:
- Stateless: Không lưu trạng thái giữa các request.
- Client-Server: Phân chia rõ ràng giữa client và server.
- Cacheable: Hỗ trợ caching để tối ưu hiệu năng.
- Layered System: Kiến trúc phân lớp giúp hệ thống linh hoạt và dễ mở rộng.
🛠️ Cách REST API hoạt động với Flutter:
Trong khóa học này, bạn sẽ học cách:
- Gọi REST API bằng thư viện http và dio.
- Xử lý response, parse JSON thành model.
- Xử lý lỗi và hiển thị thông báo thân thiện.
- Tích hợp REST API vào các màn hình Flutter với quản lý trạng thái.
🎯 MỤC TIÊU KHÓA HỌC:
- 🚀 Xây dựng ứng dụng Flutter kết nối Backend, API mượt mà.
- 🚀 Tích hợp các tính năng AI tiên tiến vào mobile app.
- 🚀 Phát triển ứng dụng real-time với Firebase Cloud Firestore & WebSocket.
- 🚀 Thành thạo quản lý trạng thái với Provider, Riverpod, BLoC.
- 🚀 Triển khai backend cơ bản với Node.js + Express.
- 🚀 Tối ưu hiệu năng và đưa ứng dụng lên Google Play & App Store.
👩💻👨💻 ĐỐI TƯỢNG HỌC VIÊN:
- Lập trình viên Flutter muốn nâng cao kỹ năng.
- Mobile Developer phát triển ứng dụng kết nối API & Backend.
- Backend Developer học cách tích hợp API vào Flutter.
- AI Enthusiast khám phá ứng dụng AI trên mobile app.
- Sinh viên/Freelancer xây dựng ứng dụng thực tế với API & AI.
Tích hợp AI vào ứng dụng Flutter — ba kiến trúc thực tế
Tích hợp AI không chỉ là "gọi một API". Có ba cách tiếp cận với đánh đổi rất khác nhau.
Kiến trúc 1 — App gọi thẳng API của nhà cung cấp
Flutter App ──(API key)──> OpenAI / Gemini / Claude
Future<String> hoiAI(String cauHoi) async {
final r = await http.post(
Uri.parse('https://api.openai.com/v1/chat/completions'),
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer $apiKey',
},
body: jsonEncode({
'model': 'gpt-4o-mini',
'messages': [
{'role': 'system', 'content': 'Trả lời ngắn gọn bằng tiếng Việt.'},
{'role': 'user', 'content': cauHoi},
],
}),
);
return jsonDecode(r.body)['choices'][0]['message']['content'];
}
| Ưu điểm | Nhược điểm |
|---|---|
| Nhanh để làm prototype | 🔴 API key nằm trong app — ai cũng lấy được |
| Không cần backend | Không kiểm soát được chi phí |
| Không cache, không rate limit |
🔴 Cảnh báo: giải nén file APK và tìm chuỗi
sk-mất chưa đến một phút. Nếu bạn làm cách này và đẩy lên store, key sẽ bị lấy và dùng hết quota trong vài ngày. Chỉ dùng cho prototype nội bộ.
Kiến trúc 2 — Qua backend trung gian (khuyến nghị)
Flutter App ──> Backend của bạn ──> OpenAI / Gemini
│
├── giữ API key
├── cache câu trả lời
├── rate limit theo user
└── log chi phí
// App chỉ gọi backend của bạn — không bao giờ biết API key
Future<String> hoiAI(String cauHoi) async {
final json = await api.post('/ai/hoi', {'cau_hoi': cauHoi});
return json['tra_loi'] as String;
}
Backend (FastAPI) giữ key và kiểm soát chi phí:
from fastapi import FastAPI, Depends, HTTPException
from pydantic import BaseModel, Field
from openai import OpenAI
import redis
app = FastAPI()
client = OpenAI()
r = redis.from_url("redis://localhost")
QUOTA_MOI_NGAY = 50
class CauHoi(BaseModel):
cau_hoi: str = Field(min_length=1, max_length=2000)
async def kiem_tra_quota(user_id: int):
khoa = f"quota:ai:{user_id}"
so_lan = r.incr(khoa)
if so_lan == 1:
r.expire(khoa, 86400)
if so_lan > QUOTA_MOI_NGAY:
raise HTTPException(429, f"Đã dùng hết {QUOTA_MOI_NGAY} lượt hôm nay")
@app.post("/ai/hoi")
async def hoi(du_lieu: CauHoi, _=Depends(kiem_tra_quota)):
# Cache theo nội dung — cùng câu hỏi không tốn tiền hai lần
khoa_cache = f"ai:cache:{hash(du_lieu.cau_hoi)}"
if (da_cache := r.get(khoa_cache)):
return {"tra_loi": da_cache.decode(), "tu_cache": True}
phan_hoi = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "Trả lời ngắn gọn bằng tiếng Việt."},
{"role": "user", "content": du_lieu.cau_hoi},
],
)
tra_loi = phan_hoi.choices[0].message.content
r.setex(khoa_cache, 3600, tra_loi)
return {"tra_loi": tra_loi, "tu_cache": False}
Ba lợi ích cụ thể: key được bảo vệ; cache giảm chi phí đáng kể (câu hỏi lặp lại rất phổ biến trong app thật); rate limit theo user ngăn một người dùng phá hỏng quota của tất cả.
Kiến trúc 3 — Model chạy trên thiết bị
import 'package:tflite_flutter/tflite_flutter.dart';
class PhanLoaiAnh {
Interpreter? _interpreter;
Future<void> tai() async {
_interpreter = await Interpreter.fromAsset('assets/model.tflite');
}
/// Phân loại ảnh — chạy hoàn toàn offline, không gửi dữ liệu lên mạng
List<double> duDoan(List<double> dauVao) {
final ketQua = List.filled(10, 0.0).reshape([1, 10]);
_interpreter!.run(dauVao.reshape([1, 224, 224, 3]), ketQua);
return List<double>.from(ketQua[0]);
}
}
| Tiêu chí | Trên thiết bị | Qua API |
|---|---|---|
| Chi phí mỗi lần gọi | 0 | Theo token |
| Cần mạng | ❌ Không | ✅ Có |
| Riêng tư dữ liệu | ✅ Rất tốt | ⚠️ Dữ liệu lên server |
| Kích thước app | Tăng vài MB — vài trăm MB | Không đổi |
| Chất lượng model | Giới hạn | Tút nhất |
| Tốc độ | Tuỳ thiết bị | Ổn định |
Khi nào chọn trên thiết bị: dữ liệu nhạy cảm (y tế, tài chính cá nhân), cần hoạt động offline, hoặc model nhỏ đã đủ tốt (OCR, phát hiện khuôn mặt, phân loại đơn giản).
Streaming — trải nghiệm người dùng tốt hơn nhiều
Thay vì chờ 5 giây rồi hiện cả đoạn văn, hãy hiện dần từng từ.
Stream<String> hoiAIStream(String cauHoi) async* {
final request = http.Request('POST', Uri.parse('$baseUrl/ai/hoi-stream'))
..headers['Content-Type'] = 'application/json'
..body = jsonEncode({'cau_hoi': cauHoi});
final phanHoi = await request.send();
await for (final dong in phanHoi.stream
.transform(utf8.decoder)
.transform(const LineSplitter())) {
if (dong.startsWith('data: ')) {
final duLieu = dong.substring(6).trim();
if (duLieu == '[DONE]') break;
try {
yield jsonDecode(duLieu)['delta'] as String? ?? '';
} catch (_) {
continue; // bỏ qua chunk bị cắt giữa
}
}
}
}
Dùng với StreamBuilder, chữ sẽ xuất hiện dần — trải nghiệm cảm giác nhanh hơn nhiều dù tổng thời gian bằng nhau.
Bốn sai lầm khi tích hợp AI
- Để API key trong app. Key sẽ bị lấy. Luôn qua backend.
- Không giới hạn số lần gọi. Một user có thể đốt hết ngân sách của bạn trong một ngày.
- Không cache. Câu hỏi "app này là gì?" được hỏi hàng nghìn lần — mỗi lần tốn tiền.
- Không xử lý khi AI trả lời sai. Luôn có fallback và cho người dùng báo cáo câu trả lời kém.
📚 Tài liệu khóa học
- Syllabus khóa học: Xem chi tiết tại đây
- Tài liệu khóa học: Cung cấp trong buổi học
- Đăng ký tham gia khóa học: http://zalo.me/0583587833
Hẹn gặp các bạn vào ngày khai giảng! 🚀