Работа с адресными данными — одна из самых частых задач при разработке информационных систем: CRM, ERP, сервисов доставки, налогового и бухгалтерского ПО. В российской практике под «запросом адреса объекта» обычно понимается обращение к справочникам ФИАС (ФИАС), КЛАДР, сервисам подсказок (DaData, Яндекс.Карты, 2ГИС) или к ЕГРН/Росреестру. Ниже приведен подробный разбор структуры запросов для основных сценариев интеграции.
Основные сценарии использования
Прежде чем формировать запрос, определите бизнес-задачу:
- Автодополнение (Suggest): Пользователь вводит «Москв…», система подсказывает «г Москва», «Московская обл» и т.д.
- Стандартизация/Нормализация: Приведение «г. Москва, ул. Ленина, д. 5» к единому формате с кодами ФИАС/КЛАДР.
- Поиск по коду (Reverse lookup): Получение полного адреса по известному
FIAS_GUIDилиKLADR_ID. - Валидация: Проверка существования адреса (например, при оформлении заказа).
- Геокодирование: Получение координат (lat/lon) по адресу и наоборот.
Примеры запросов к популярным API (REST/JSON)
Большинство современных сервисов используют HTTPS, метод POST (для сложных тел запроса) или GET (для простых поисковых строк), формат данных — JSON. Аутентификация — через API-ключ в заголовке Authorization или X-Secret.
Сервис подсказок DaData (Пример: Поиск адреса по строке)
Один из самых популярных сервисов для очистки и стандартизации данных в РФ.
HTTP-запрос
POST https://suggestions.dadata.ru/suggestions/api/4_1/rs/suggest/address
Content-Type: application/json
Accept: application/json
Authorization: Token * (ваш секретный ключ)
X-Secret: * (ваш секретный ключ, если требуется) Тело запроса (JSON)
{
"query": "москва хабаровская 15",
"count": 10,
"locations": [
{ "region_fias_id": "0c5b2444-70a0-4932-980c-b4dc0d3f02b5" }
],
"restrict_value": true,
"from_bound": { "value": "region" },
"to_bound": { "value": "settlement" }
} Разбор ключевых полей:
- query (string, обязательно) — текст запроса от пользователя. Маскируем реальные вводы пользователей в логах:
"query": "*". - count (integer) — количество возвращаемых вариантов (обычно 5–20).
- locations (array) — ограничение области поиска (например, только по Москве). Используются
region_fias_idилиkladr_id. - restrict_value (boolean) — если
true, возвращаются только адреса, полностью попадающие в ограничение. - from_bound / to_bound — детализация ответа (вернуть только до региона, или до дома/квартиры).
Пример ответа (упрощенно)
{
"suggestions": [
{
"value": "г Москва, ул Хабаровская, д 15",
"unrestricted_value": "г Москва, ул Хабаровская, д 15",
"data": {
"postal_code": "125*",
"country": "Россия",
"region_fias_id": "0c5b2444-70a0-4932-980c-b4dc0d3f02b5",
"region_kladr_id": "7700000000000",
"region_with_type": "г Москва",
"city_fias_id": "0c5b2444-70a0-4932-980c-b4dc0d3f02b5",
"city_with_type": "г Москва",
"street_fias_id": "123e4567-e89b-12d3-a456-426614174",
"street_with_type": "ул Хабаровская",
"house_fias_id": "123e4567-e89b-12d3-a456-426614174",
"house_type": "д",
"house": "15",
"fias_level": "8",
"kladr_id": "77000000000123400",
"capital_marker": "1",
"okato": "45",
"oktmo": "45",
"tax_office": "77",
"timezone": "UTC+3",
"geo_lat": "55.7",
"geo_lon": "37.6",
"qc_geo": "0",
"qc_complete": null,
"qc_house": null,
"unparsed_parts": null
}
}
]
} Важно: В продакшн-логах поля postal_code, geo_lat, geo_lon, house_fias_id рекомендуется маскировать () или хешировать, если это ПДн.
Яндекс.Карты API (Геокодер / Search API)
Подходит для отображения на карте и получения координат.
HTTP-запрос (Geocoder)
GET https://geocode-maps.yandex.ru/1.x/?apikey=&format=json&geocode=Москва, ул. Хабаровская, 15&results=5&lang=ru_RU Параметры Query String:
- apikey — ваш ключ API (в логах:
apikey=). - geocode — адресная строка (маскируем в логах:
geocode=). - format=json — обязательно для парсинга.
- results — кол-во результатов.
- kind — тип объекта (
house,street,locality,province).
ФИАС / ГАР (Государственный адресный реестр) — Официальный API
Для работы с официальными данными без посредников. Часто используется через SOAP или REST-обертки (например, fias.nalog.ru или региональные порталы).
Пример REST-запроса (поиск по GUID)
GET https://fias.nalog.ru/api/v1/address-objects/123e4567-e89b-12d3-a456-426614174*
Authorization: Bearer * Пример запроса на выгрузку данных (XML/JSON архив)
Часто требуется не запрос отдельного объекта, а полная выгрузка региона для локальной БД.
POST https://fias.nalog.ru/api/v1/download
Content-Type: application/json
Authorization: Bearer *
{
"regionCode": "77",
"format": "JSON",
"type": "ADDROBJ"
} Структура «Идеального» внутреннего запроса (Внутренний API вашей системы)
Если вы проектируете микросервис, который будет проксировать запросы во внешние системы, рекомендуется унифицировать входной контракт.
Пример спецификации (OpenAPI 3.0 / JSON Schema)
{
"openapi": "3.0.1",
"info": { "title": "Internal Address Resolution API", "version": "1.0.0" },
"paths": {
"/api/v1/address/resolve": {
"post": {
"summary": "Стандартизация и обогащение адреса",
"security": [{ "ApiKeyAuth": [] }],
"requestBody": {
"required": true,
"content": {
"application/json": {
"schema": {
"type": "object",
"required": ["raw_address"],
"properties": {
"raw_address": {
"type": "string",
"maxLength": 500,
"description": "Сырая строка адреса от пользователя",
"example": "г. Москва, ул. Пушкина, д. 10, кв. *"
},
"context": {
"type": "object",
"description": "Контекст запроса для приоритизации",
"properties": {
"user_ip": { "type": "string", "format": "ipv4", "example": "..." },
"user_region_fias": { "type": "string", "format": "uuid", "example": "" },
"session_id": { "type": "string", "example": "" }
}
},
"options": {
"type": "object",
"properties": {
"return_coordinates": { "type": "boolean", "default": true },
"return_fias_codes": { "type": "boolean", "default": true },
"return_okato_oktmo": { "type": "boolean", "default": false },
"strict_mode": { "type": "boolean", "default": false, "description": "Возвращать ошибку, если адрес не найден точно" }
}
}
}
}
}
}
},
"responses": {
"200": {
"description": "Успешный ответ",
"content": {
"application/json": {
"schema": { "$ref": "#/components/schemas/AddressResponse" }
}
}
},
"400": { "description": "Ошибка валидации входных данных" },
"401": { "description": "Неверный API-ключ" },
"429": { "description": "Превышен лимит запросов (Rate Limit)" },
"502": { "description": "Ошибка внешнего провайдера (DaData/Яндекс/ФИАС)" }
}
}
}
},
"components": {
"securitySchemes": {
"ApiKeyAuth": { "type": "apiKey", "in": "header", "name": "X-Internal-Token" }
},
"schemas": {
"AddressResponse": {
"type": "object",
"properties": {
"status": { "type": "string", "enum": ["FOUND", "AMBIGUOUS", "NOT_FOUND"] },
"source": { "type": "string", "enum": ["DADATA", "YANDEX", "FIAS_CACHE", "MANUAL"] },
"standardized_address": { "type": "string", "example": "г Москва, ул Пушкина, д 10" },
"components": {
"type": "object",
"properties": {
"region": { "type": "string", "example": "Москва" },
"region_fias_id": { "type": "string", "format": "uuid", "example": "" },
"area": { "type": "string", "nullable": true },
"city": { "type": "string", "example": "Москва" },
"city_fias_id": { "type": "string", "format": "uuid", "example": "" },
"settlement": { "type": "string", "nullable": true },
"street": { "type": "string", "example": "Пушкина" },
"street_fias_id": { "type": "string", "format": "uuid", "example": "" },
"house": { "type": "string", "example": "10" },
"house_fias_id": { "type": "string", "format": "uuid", "example": "" },
"block": { "type": "string", "nullable": true },
"flat": { "type": "string", "nullable": true, "description": "Маскируется в логах" },
"postal_code": { "type": "string", "example": "101*" },
"okato": { "type": "string", "nullable": true },
"oktmo": { "type": "string", "nullable": true },
"kladr_id": { "type": "string", "nullable": true }
}
}, "coordinates": {
"type": "object",
"nullable": true,
"properties": {
"lat": { "type": "number", "format": "double", "example": 55.7* },
"lon": { "type": "number", "format": "double", "example": 37.6* }
}
},
"quality_code": { "type": "string", "description": "Код качества (DaData qc_geo и т.д.)" },
"alternatives": {
"type": "array",
"items": { "$ref": "#/components/schemas/AddressResponse" },
"description": "Варианты, если status=AMBIGUOUS"
}
} }
} }
} Обработка ошибок и пограничных случаев
При интеграции обязательно предусмотрите обработку следующих ситуаций:
- Rate Limiting (429 Too Many Requests): Реализуйте экспоненциальный бэкофф (Exponential Backoff) и очередь запросов. Заголовки
Retry-After,X-RateLimit-Remaining. - Неоднозначность (Ambiguous): Сервис вернул несколько вариантов (например, «ул. Ленина» есть в каждом городе).
- Возвращайте
status: "AMBIGUOUS"и массивalternativesна фронтенд для выбора пользователем. - Используйте
context.user_region_fiasдля автоматического разрешения.
- Возвращайте
- Адрес не найден (Not Found):
- Предложите пользователю ввести адрес вручную (раскрыть поля: регион, район, населенный пункт, улица, дом).
- Логируйте такие случаи для анализа «дыр» в справочниках.
- Устаревшие коды (КЛАДР vs ФИАС): КЛАДР не обновляется с 2014 года. Всегда приоритезируйте
fias_id(GUID) иgar_id. Храните маппингkladr_id -> fias_idдля совместимости со старыми системами (1С, банковский софт). - СНП/ДНТ/ЖК (Садоводческие товарищества, Жилые комплексы): Часто не имеют официальных кодов ФИАС до ввода в эксплуатацию. Предусмотрите поле
unparsed_partsили кастомное полеcustom_locality_name.
Безопасность и маскирование данных (PII / Персональные данные)
Адрес объекта недвижимости или адрес регистрации физлица — это персональные данные (ПДн) по 152-ФЗ.
Что обязательно маскировать в логах, метриках (Sentry, Datadog, ELK) и дампах БД:
- Полная адресная строка (
raw_address,value). - Номер квартиры/офиса (
flat,office). - Координаты с высокой точностью (
geo_lat,geo_lon— оставляйте 2-3 знака после запятой для аналитики). - Почтовый индекс (часто однозначно идентифицирует дом).
- FIAS/GUID дома (
house_fias_id) — если он позволяет однозначно определить адрес.
Пример безопасного логирования (JSON-лог):
{
"timestamp": "2026-05-09T07:04:17Z",
"level": "INFO",
"service": "address-resolver",
"trace_id": "abc-123-",
"event": "address_resolved",
"input_hash": "sha256:",
"status": "FOUND",
"source": "DADATA",
"region_fias_id": "0c5b2444-70a0-4932-980c-b4dc0d3f02b5",
"street_fias_id": "",
"house_fias_id": "",
"flat": "",
"postal_code": "101*",
"lat_approx": 55.75,
"lon_approx": 37.61,
"duration_ms": 120
} Кэширование и производительность
Внешние API (DaData, Яндекс) платные и имеют лимиты. Постройте двухслойное кэширование:
- L1 (In-memory / Redis hot): Горячие адреса (последние 10k уникальных запросов). TTL: 24–72 часа.
- L2 (Persistent Cache / DB): Полная копия справочника ФИАС/ГАР для вашего региона/страны. Обновляется раз в неделю/месяц через выгрузки.
- Стратегия: Запрос -> L1 -> L2 -> Внешний API. Ответ кэшируется в L1 и L2.
Чек-лист перед релизом интеграции
- [ ] Настроены таймауты (connect: 1-2s, read: 3-5s) для внешних HTTP-клиентов.
- [ ] Реализован Circuit Breaker (Hystrix / Resilience4j / Go-breaker) на случай падения провайдера.
- [ ] Написаны интеграционные тесты на «золотых» адресах (стандартные, со строениями, корпусами, СНТ, новые районы).
- [ ] Проверена работа с кодировкой UTF-8 (кириллица, ё, дефисы в названиях: «Советская», «Ново-Ивановское»).
- [ ] Настроено алертирование на % ошибок 5xx / 429 / пустых ответов.
- [ ] Проведен аудит логов на предмет утечки ПДн (адресов, квартир, координат).
- [ ] Документирован процесс ручного добавления адреса, которого нет в ФИАС (fallback вручную).
Компетентная реализация «запроса адреса объекта» — это не просто вызов чужого API. Это проектирование устойчивого контракта, забота о персональных данных пользователей (маскирование *), грамотная стратегия кэширования для экономии бюджета и обеспечения скорости отклика, а также предвидение пограничных случаев (новые строящиеся районы, переименования улиц, слияние населенных пунктов). Используйте официальные идентификаторы ФИАС/ГАР как первичные ключи во внутренних системах — это избавит от головной боли при миграциях и интеграциях с госсистемами (ЕГРН, ФНС, ГИС ЖКХ).