1. Giới thiệu
Hôm nay hầu như mọi ứng dụng hiện đại đều sử dụng dữ liệu từ Internet. Khi bạn mở xem thời tiết trên điện thoại, đặt taxi hoặc đọc tin tức — đó luôn là kết quả của việc làm việc với API. Các chương trình “trò chuyện” với nhau, trao đổi thông điệp, và thường những thông điệp này ở dạng văn bản đơn giản — định dạng JSON.
JSON (JavaScript Object Notation) đã trở thành tiêu chuẩn trao đổi dữ liệu giữa các dịch vụ. Cả lập trình viên lẫn máy đều “ưa thích” nó: con người dễ đọc văn bản, còn chương trình thì dễ phân tích. JSON chỉ có vài quy tắc:
- dữ liệu được lưu dưới dạng đối tượng kiểu từ điển { "key": value },
- hoặc mảng [value1, value2],
- hoặc là các chuỗi, số, giá trị boolean và null đơn giản.
Ví dụ, một JSON object mô tả một người có thể trông như sau:
{
"name": "Alice",
"age": 25,
"skills": ["Java", "Python", "SQL"]
}
Ta thấy các khóa (name, age, skills) và giá trị của chúng. Gọn, trực quan và phổ dụng.
2. Làm quen với API
API (Application Programming Interface) là một “thỏa thuận” hay “hợp đồng” nói rằng: nếu bạn gửi yêu cầu đến một địa chỉ Internet xác định và cung cấp các tham số nhất định, tôi sẽ trả về phản hồi theo định dạng đã thống nhất.
Địa chỉ mà ta gọi để lấy dữ liệu được gọi là endpoint. Đó đơn giản là một URL. Thường trong đó có các tham số của yêu cầu — gọi là tham số truy vấn.
Ví dụ, URL sau trả về dự báo thời tiết cho Minsk:
https://api.open-meteo.com/v1/forecast?latitude=50.45&longitude=30.52¤t_weather=true
Nếu để ý, sau dấu ? là danh sách các tham số:
- latitude = 50.45 — vĩ độ,
- longitude = 30.52 — kinh độ,
- current_weather = true — muốn thời tiết hiện tại.
Một số API còn yêu cầu “mật khẩu” — khóa API. Khi đó nó được thêm vào tham số, ví dụ & apikey = YOUR_KEY.
Bạn có thể xem tài liệu của dịch vụ thời tiết tại trang open-meteo.com.
3. Phản hồi API trông như thế nào?
Khi chúng ta gửi yêu cầu, máy chủ trả lời bằng văn bản: một chuỗi JSON. Đôi khi đó là JSON object, đôi khi — JSON array.
Ví dụ phản hồi về thời tiết:
{
"latitude": 50.45,
"longitude": 30.52,
"current_weather": {
"temperature": 21.3,
"windspeed": 5.2,
"weathercode": 1
}
}
Ví dụ phản hồi của dịch vụ cung cấp toạ độ ISS:
{
"timestamp": 1717590000,
"iss_position": {
"latitude": "48.1234",
"longitude": "12.5678"
},
"message": "success"
}
4. Ví dụ đầu tiên: lấy dữ liệu thời tiết
Hãy thử viết một đoạn mã nhỏ gọi tới API thời tiết miễn phí open-meteo.com và chỉ đơn giản in phản hồi ra console.
String url = "https://api.open-meteo.com/v1/forecast?latitude=50.45&longitude=30.52¤t_weather=true";
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create(url)).GET().build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println("Trạng thái HTTP: " + resp.statusCode());
System.out.println("Phản hồi từ máy chủ:");
System.out.println(resp.body());
Ở đây chúng ta:
- Tạo một client HttpClient.
- Tạo yêu cầu GET (HttpRequest).
- Gửi yêu cầu: client.send.
- Nhận phản hồi dưới dạng chuỗi: HttpResponse<String>.
Nếu mọi thứ hoạt động, bạn sẽ thấy mã trạng thái HTTP 200 và JSON chứa dữ liệu thời tiết.
5. Ví dụ thứ hai: theo dõi ISS
Bây giờ ta gọi API open-notify.org, dịch vụ hiển thị toạ độ của Trạm Vũ trụ Quốc tế (ISS) theo thời gian thực.
String url = "http://api.open-notify.org/iss-now.json";
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create(url)).GET().build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
Kết quả sẽ trông như sau:
{
"timestamp": 1717590000,
"iss_position": {
"latitude": "48.1234",
"longitude": "12.5678"
},
"message": "success"
}
Ngay lúc này bạn đã nhận được toạ độ chính xác của trạm đang bay quanh Trái Đất. Nếu chạy lại đoạn mã này sau một phút — các con số sẽ khác.
6. Những điểm hữu ích
Khi bắt đầu làm việc với API, có một vài điều rất quan trọng cần lưu ý.
Thứ nhất, luôn kiểm tra mã trạng thái phản hồi: resp.statusCode(). Nếu là 200 — mọi thứ ổn. Nếu 404 — URL sai. Nếu 401 — cần khóa. Nếu 429 — bạn đang gửi quá nhiều yêu cầu.
Thứ hai, nhớ về giới hạn. Các dịch vụ miễn phí giới hạn tần suất yêu cầu để tránh quá tải máy chủ.
Thứ ba, JSON không phải lúc nào cũng “đẹp”. Đôi khi nó là một chuỗi rất dài trên một dòng — điều đó là bình thường. Sau này chúng ta sẽ học cách dùng các thư viện (Jackson, Gson) để “phân tách” JSON thành các trường và làm việc với chúng như với các đối tượng.
Một thử nghiệm nhỏ nữa
Hãy thử một API trả về một sự thật ngẫu nhiên về mèo:
String url = "https://catfact.ninja/fact";
HttpClient client = HttpClient.newHttpClient();
HttpRequest req = HttpRequest.newBuilder(URI.create(url)).GET().build();
HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(resp.body());
Hãy chạy đoạn mã này vài lần, mỗi lần bạn sẽ nhận được một JSON mới với một thông tin thú vị.
GO TO FULL VERSION