# Документация API METARTAF

Программный доступ к актуальным авиационным метеосводкам METAR и TAF.

Базовый адрес: `https://metartaf.ru`

---

## API v1 (Рекомендуется)

Современный REST-подобный интерфейс с поддержкой JSON, XML и простого текста.

### Адреса

- `GET https://metartaf.ru/api/v1/stations/{icao}/latest` — сводки METAR и TAF
- `GET https://metartaf.ru/api/v1/stations/{icao}/metar/latest` — только METAR
- `GET https://metartaf.ru/api/v1/stations/{icao}/taf/latest` — только TAF

Код станции `{icao}` — четырёхбуквенный код ICAO (например, `UUEE`). Код в нижнем регистре перенаправляется ответом `301 Moved Permanently` на канонический адрес в верхнем регистре с сохранением параметров запроса.

### Правила выбора формата

Формат ответа определяется в следующем порядке:

1. **Параметр запроса `format`** (без учёта регистра):
   - `?format=json` → JSON
   - `?format=xml` → XML
   - `?format=raw` → простой текст
   - Имеет приоритет над заголовком `Accept`.
2. **Заголовок запроса `Accept`**:
   - `application/json` → JSON
   - `application/xml` или `text/xml` → XML
   - `text/plain` → простой текст (raw)
   - Параметры типов (например, `charset=utf-8`) игнорируются.
   - Выбирается формат с наибольшим значением `q` (например, `Accept: application/json;q=0.5, text/plain;q=0.9` выбирает простой текст).
   - При равенстве значений приоритет отдаётся: **JSON > XML > raw**.
   - `q=0` недопустимо.
   - Символы подстановки (например, `*/*`) не определяют формат.
3. **По умолчанию**:
   - Если формат не указан, возвращается **JSON** (`application/json; charset=utf-8`).

### Схемы ответов

#### 1. JSON (`application/json; charset=utf-8`)

Поля корневого объекта:
- `icao` (строка): 4-буквенный код станции ICAO.
- `name` (строка): название аэропорта или станции.
- `metar` (объект | null): присутствует в `/latest` и `/metar/latest`. Содержит `observed_at` (строка времени ISO 8601 UTC) и `raw` (строка с текстом METAR). `null`, если сводка недоступна.
- `taf` (объект | null): присутствует в `/latest` и `/taf/latest`. Содержит `issued_at` (строка времени ISO 8601 UTC) и `raw` (строка с текстом TAF). `null`, если сводка недоступна.

Пример (`GET https://metartaf.ru/api/v1/stations/UUEE/latest`):
```json
{
  "icao": "UUEE",
  "name": "Sheremetyevo",
  "metar": {
    "observed_at": "2026-10-30T14:30:00Z",
    "raw": "UUEE 301430Z 19004MPS 9999 BKN040 03/M01 Q1012 NOSIG"
  },
  "taf": {
    "issued_at": "2026-10-30T11:00:00Z",
    "raw": "TAF UUEE 301100Z 3012/3112 20004MPS 9999 BKN040"
  }
}
```

#### 2. XML (`application/xml; charset=utf-8`)

Корневой элемент `<report>`:
- `<icao>`: код станции.
- `<name>`: название аэропорта или станции.
- `<metar observed_at="ISO-8601-UTC">`: текст METAR. Тег отсутствует, если сводка недоступна или не запрошена.
- `<taf issued_at="ISO-8601-UTC">`: текст TAF. Тег отсутствует, если сводка недоступна или не запрошена.

Пример (`GET https://metartaf.ru/api/v1/stations/UUEE/latest?format=xml`):
```xml
<?xml version="1.0" encoding="UTF-8"?>
<report>
  <icao>UUEE</icao>
  <name>Sheremetyevo</name>
  <metar observed_at="2026-10-30T14:30:00Z">UUEE 301430Z 19004MPS 9999 BKN040 03/M01 Q1012 NOSIG</metar>
  <taf issued_at="2026-10-30T11:00:00Z">TAF UUEE 301100Z 3012/3112 20004MPS 9999 BKN040</taf>
</report>
```

#### 3. Простой текст (`text/plain; charset=utf-8`)

- **Оба отчёта (`/api/v1/stations/{icao}/latest?format=raw`)**: содержит строки заголовков `METAR` и `TAF` (`METAR\n<metar>\nTAF\n<taf>\n`). Если отчёт недоступен, блок под его заголовком остаётся пустым.
- **Одиночные отчёты (`/metar/latest?format=raw` и `/taf/latest?format=raw`)**: возвращают **только** строку самого отчёта со знаком перевода строки `\n` **без** заголовков `METAR`/`TAF`. Если отчёт недоступен, возвращается только перевод строки `\n`.

Пример для обоих отчётов (`GET https://metartaf.ru/api/v1/stations/UUEE/latest?format=raw`):
```text
METAR
UUEE 301430Z 19004MPS 9999 BKN040 03/M01 Q1012 NOSIG
TAF
TAF UUEE 301100Z 3012/3112 20004MPS 9999 BKN040
```

Пример только для METAR (`GET https://metartaf.ru/api/v1/stations/UUEE/metar/latest?format=raw`):
```text
UUEE 301430Z 19004MPS 9999 BKN040 03/M01 Q1012 NOSIG
```

### Формат ошибок

Ошибки всегда возвращают объект JSON с полями `error` и `message`:
```json
{
  "error": "...",
  "message": "..."
}
```

- `400 Bad Request` (`error: "unsupported_format"`): неподдерживаемый формат (например, `?format=yaml`).
- `404 Not Found` (`error: "station_not_found"`): станция ICAO неизвестна или отсутствует в базе.
- `500 Internal Server Error` (`error: "internal_error"`): внутренняя ошибка сервера.

### Примеры curl

```bash
# JSON (по умолчанию)
curl https://metartaf.ru/api/v1/stations/UUEE/latest

# Выбор XML через заголовок Accept
curl -H 'Accept: application/xml' https://metartaf.ru/api/v1/stations/UUEE/latest

# Параметр format переопределяет заголовок Accept
curl -H 'Accept: application/xml' 'https://metartaf.ru/api/v1/stations/UUEE/latest?format=json'

# Только сводка METAR простым текстом
curl 'https://metartaf.ru/api/v1/stations/UUEE/metar/latest?format=raw'

# Переход по 301-редиректу для кода станции в нижнем регистре
curl -L 'https://metartaf.ru/api/v1/stations/uuee/latest?format=raw'
```

---

## API v0 (Устаревшая версия)

Предыдущая версия API, сохраняемая для обратной совместимости.

### Адреса

- `GET https://metartaf.ru/{ICAO}.json` — returns JSON (`application/json; charset=utf-8`), selected by `.json` extension (`Accept` header is ignored)
- `GET https://metartaf.ru/{ICAO}.xml` — returns XML (`application/xml; charset=utf-8`), selected by `.xml` extension (`Accept` header is ignored)

### Формат и особенности

- Ответ представляет собой плоский объект из четырёх строковых полей (`{"icao": "...", "name": "...", "metar": "...", "taf": "..."}`).
- Текст сводок METAR и TAF содержит временную метку с секундами первой строкой: `YYYY-MM-DD HH:MM:SS\n` (например, `2026-10-30 14:30:00\nUUEE 301430Z...`).
- При отсутствии сводки возвращается русский текст `"Информация по данной станции не доступна"` вместо `null`.
- Для неизвестной станции возвращается пустой ответ `404 Not Found`.