Get Airports - Lấy Danh Sách Sân Bay
API Endpoint: GET /api/v1/current/airports
📋 Overview
Lấy danh sách tất cả sân bay khả dụng để user chọn điểm đi/điểm đến.
Use Case:
- Populate dropdown "Từ" (departure airport)
- Populate dropdown "Đến" (arrival airport)
- Search/filter airports by name or code
Result: 6,073 airports worldwide
🔌 API Specification
Endpoint
GET {{base_url}}/api/v1/current/airports
Headers
{
"Content-Type": "application/json",
"Accept": "application/json",
"Authorization": "Bearer {access_token}"
}
Query Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
page | number | ❌ | 1 | Page number for pagination |
limit | number | ❌ | 9999 | Number of items per page |
q | string | ❌ | - | Search by name or code (e.g., "Hanoi", "SGN") |
departure | string | ❌ | - | Filter by departure capability |
airlines | string[] | ❌ | - | Filter by airline codes (e.g., ["VJ"]) |
Examples:
# Get all airports (recommended for initial load)
GET /api/v1/current/airports?page=1&limit=9999
# Search airports
GET /api/v1/current/airports?q=Hanoi&limit=10
# Filter by airline
GET /api/v1/current/airports?airlines=VJ&limit=9999
✅ Success Response
Status: 200 OK
{
"data": [
{
"id": "77e71f43-bb75-4e48-b6e6-0ce087359919",
"type": "airport",
"attributes": {
"id": "77e71f43-bb75-4e48-b6e6-0ce087359919",
"name": "Tan Son Nhat International Airport",
"code": "SGN",
"iata": "SGN",
"icao": "VVTS",
"domestic": true,
"active": true,
"iso_name": "Tan Son Nhat International Airport",
"city": "Ho Chi Minh City",
"country_name": "Vietnam",
"lat": 10.8188,
"lon": 106.6519,
"timezone": "7",
"tz": "Asia/Ho_Chi_Minh",
"airport_type": "airport",
"order_index": 0,
"search_count": 0,
"country": {}
}
},
{
"id": "31ba2fc7-d1dd-4373-a482-4dedd77e7852",
"type": "airport",
"attributes": {
"id": "31ba2fc7-d1dd-4373-a482-4dedd77e7852",
"name": "Noi Bai International Airport",
"code": "HAN",
"iata": "HAN",
"icao": "VVNB",
"domestic": true,
"active": true,
"iso_name": "Noi Bai International Airport",
"city": "Hanoi",
"country_name": "Vietnam",
"lat": 21.2212,
"lon": 105.8072,
"timezone": "7",
"tz": "Asia/Ho_Chi_Minh",
"airport_type": "airport",
"order_index": 0,
"search_count": 0,
"country": {}
}
}
]
}
Response Fields:
| Field | Type | Description |
|---|---|---|
data | array | Array of airport objects |
data[].id | string | UUID của airport |
data[].type | string | Luôn là "airport" |
data[].attributes | object | Airport details |
Attributes Object:
| Field | Type | Description | Example |
|---|---|---|---|
id | string | Airport UUID | "77e71f43-bb75..." |
name | string | Tên đầy đủ | "Tan Son Nhat International Airport" |
code | string | Airport code (IATA) | "SGN" |
iata | string | IATA code | "SGN" |
icao | string | ICAO code | "VVTS" |
domestic | boolean | Sân bay nội địa | true |
active | boolean | Đang hoạt động | true |
iso_name | string | ISO name | "Tan Son Nhat..." |
city | string | Thành phố | "Ho Chi Minh City" |
country_name | string | Quốc gia | "Vietnam" |
lat | number | Latitude | 10.8188 |
lon | number | Longitude | 106.6519 |
timezone | string | UTC offset | "7" |
tz | string | Timezone | "Asia/Ho_Chi_Minh" |
airport_type | string | Loại | "airport" |
order_index | number | Thứ tự sắp xếp | 0 |
search_count | number | Số lần tìm kiếm | 0 |
💡 Example: cURL
curl -X GET "{{base_url}}/api/v1/current/airports?page=1&limit=9999" \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "Authorization: Bearer {access_token}"
🔍 Usage Examples
Example 1: Get All Airports (Initial Load)
// Get all airports for dropdown
const airports = await getAirports(accessToken);
// Build dropdown options
const options = airports.map((airport) => ({
value: airport.attributes.code,
label: `${airport.attributes.city} (${airport.attributes.code})`,
name: airport.attributes.name,
}));
Output:
[
{ value: "SGN", label: "Ho Chi Minh City (SGN)", name: "Tan Son Nhat..." },
{ value: "HAN", label: "Hanoi (HAN)", name: "Noi Bai International..." },
{ value: "DAD", label: "Da Nang (DAD)", name: "Da Nang International..." },
// ... 6,070 more
];
Example 2: Search Airports
# Search by city name
curl "{{base_url}}/api/v1/current/airports?q=Hanoi&limit=10" \
-H "Authorization: Bearer {token}"
Response: Returns airports matching "Hanoi" (HAN, etc.)
Example 3: Filter Vietnam Domestic
const vietnamDomestic = airports.filter(
(a) =>
a.attributes.country_name === "Vietnam" && a.attributes.domestic === true,
);
console.log("Vietnam domestic airports:", vietnamDomestic.length);
// Output: ~22 airports (SGN, HAN, DAD, CXR, VCA, etc.)
🌍 Popular Vietnam Airports
| Code | City | Name | Type |
|---|---|---|---|
| SGN | Ho Chi Minh | Tan Son Nhat International | Domestic |
| HAN | Hanoi | Noi Bai International | Domestic |
| DAD | Da Nang | Da Nang International | Domestic |
| CXR | Cam Ranh (Nha Trang) | Cam Ranh International | Domestic |
| VCA | Can Tho | Can Tho International | Domestic |
| HPH | Hai Phong | Cat Bi International | Domestic |
| VII | Vinh | Vinh Airport | Domestic |
| HUI | Hue | Phu Bai International | Domestic |
| UIH | Quy Nhon | Phu Cat Airport | Domestic |
| VDO | Van Don | Van Don International | Domestic |
| DLI | Da Lat | Lien Khuong Airport | Domestic |
| PQC | Phu Quoc | Phu Quoc International | Domestic |
🎯 Integration Flow
Step 1: Load Airports on App Start
// On app initialization
const airports = await getAirports(accessToken);
localStorage.setItem("airports", JSON.stringify(airports));
Step 2: User Selects Route
// User selects
const departure = "SGN"; // From dropdown
const arrival = "HAN"; // From dropdown
Step 3: Search Flights
// Use selected codes to search
await searchFlights({
diem_di: departure,
diem_den: arrival,
ngay_di: "01-11-2025",
nguoi_lon: 1,
});
⚠️ Important Notes
1. Response Format is JSON:API
{
"data": [
{
"id": "uuid",
"type": "airport", // ← JSON:API format
"attributes": { // ← Data is in attributes
"code": "SGN",
"name": "...",
...
}
}
]
}
Access data:
airport.attributes.code; // ✅ Correct
airport.code; // ❌ Wrong (undefined)
2. Filter Active Airports
const activeAirports = airports.filter((a) => a.attributes.active === true);
3. Domestic vs International
// Vietnam domestic only
const domestic = airports.filter(
(a) =>
a.attributes.country_name === "Vietnam" && a.attributes.domestic === true,
);
// International
const international = airports.filter((a) => a.attributes.domestic === false);
4. Code Usage
For flight search, use attributes.code:
{
"diem_di": airport.attributes.code, // "SGN"
"diem_den": airport.attributes.code // "HAN"
}
🐛 Troubleshooting
❌ Empty Response
Cause: Missing or invalid Authorization token
Solution:
// Ensure token is valid
const response = await getAirports(accessToken);
if (!response.data || response.data.length === 0) {
// Re-authenticate
accessToken = await authenticate();
response = await getAirports(accessToken);
}
❌ "Cannot read property 'code' of undefined"
Cause: Accessing airport.code instead of airport.attributes.code
Solution:
// ❌ Wrong
const code = airport.code;
// ✅ Correct
const code = airport.attributes.code;
📖 Frontend Integration Example
React Component
import { useEffect, useState } from 'react';
import { Select } from 'antd';
interface Airport {
id: string;
type: string;
attributes: {
code: string;
name: string;
city: string;
country_name: string;
};
}
function AirportSelector() {
const [airports, setAirports] = useState<Airport[]>([]);
const [loading, setLoading] = useState(false);
useEffect(() => {
loadAirports();
}, []);
async function loadAirports() {
setLoading(true);
const response = await fetch(
'{{base_url}}/api/v1/current/airports?page=1&limit=9999',
{
headers: {
'Authorization': `Bearer ${accessToken}`
}
}
);
const data = await response.json();
setAirports(data.data || []);
setLoading(false);
}
const options = airports.map(airport => ({
value: airport.attributes.code,
label: `${airport.attributes.city} (${airport.attributes.code})`
}));
return (
<Select
showSearch
loading={loading}
options={options}
placeholder="Chọn sân bay"
filterOption={(input, option) =>
option.label.toLowerCase().includes(input.toLowerCase())
}
/>
);
}
🔗 Next Steps
After getting airports, proceed to search flights:
// 1. Get airports
const airports = await getAirports(accessToken);
// 2. User selects SGN → HAN
// 3. Search flights
await searchFlights({
diem_di: "SGN",
diem_den: "HAN",
ngay_di: "01-11-2025",
nguoi_lon: 1,
tre_em: 0,
em_be: 0,
});
See next doc: 02-SEARCH-FLIGHTS.md
📝 Notes
- Response chuẩn JSON:API format
- 6,073+ airports worldwide (Vietnam + International)
- Supports search, filter, pagination
- Data hiếm khi thay đổi → có thể cache
- Response size ~2.5MB → nên cache ở client
- Vietnam domestic: ~22 airports