Серверная маршрутизация — это процесс построения маршрутов на стороне сервера HERE с последующим получением готового результата через HTTP-запросы. В отличие от клиентской маршрутизации, где вычисления частично выполняются в браузере, серверный подход позволяет централизованно обрабатывать маршруты, скрывать API-ключи, объединять данные из нескольких источников и выполнять дополнительную бизнес-логику до передачи результатов клиентскому приложению.
Типичная схема взаимодействия выглядит следующим образом:
Такой подход особенно востребован в корпоративных системах, логистических платформах, транспортных сервисах и системах диспетчеризации.
Основным сервисом построения маршрутов выступает Routing API.
Запросы отправляются через HTTPS к REST-интерфейсу.
Базовый адрес:
https://router.hereapi.com/v8/routes
Минимальный набор параметров:
Пример запроса:
GET https://router.hereapi.com/v8/routes
?transportMode=car
&origin=52.53086,13.38469
&destination=52.52644,13.36888
&return=summary
&apiKey=YOUR_API_KEY
Наиболее распространённый сценарий серверной маршрутизации реализуется на платформе Node.js.
Установка библиотеки для HTTP-запросов:
npm install axios
Базовый пример получения маршрута:
const axios = require("axios");
const API_KEY = process.env.HERE_API_KEY;
async function getRoute() {
const response = await axios.get(
"https://router.hereapi.com/v8/routes",
{
params: {
transportMode: "car",
origin: "52.53086,13.38469",
destination: "52.52644,13.36888",
return: "summary",
apiKey: API_KEY
}
}
);
return response.data;
}
getRoute()
.then(console.log)
.catch(console.error);
Полученный объект содержит подробную информацию о маршруте, включая расстояние, продолжительность поездки и список сегментов.
Ответ сервера обычно содержит массив маршрутов.
Пример упрощённой структуры:
{
"routes": [
{
"sections": [
{
"summary": {
"length": 1500,
"duration": 320
}
}
]
}
]
}
Ключевые элементы:
| Поле | Назначение |
|---|---|
| routes | Список найденных маршрутов |
| sections | Участки маршрута |
| summary | Сводная информация |
| length | Длина маршрута в метрах |
| duration | Время движения в секундах |
| polyline | Геометрия маршрута |
| actions | Пошаговые инструкции |
Получение расстояния:
const route =
response.data.routes[0];
const section =
route.sections[0];
console.log(section.summary.length);
Получение времени в пути:
console.log(section.summary.duration);
Параметр transportMode определяет алгоритм расчёта.
Доступные варианты:
car
truck
pedestrian
bicycle
scooter
taxi
bus
privateBus
Пример:
params: {
transportMode: "truck",
origin,
destination,
return: "summary",
apiKey
}
При смене режима сервер HERE автоматически использует различные правила маршрутизации.
Например:
Для отображения маршрута на карте требуется его геометрия.
Запрос:
params: {
transportMode: "car",
origin,
destination,
return: "polyline",
apiKey
}
Ответ содержит закодированную полилинию:
{
"polyline": "BFoz5xJ67i1B1B7P..."
}
Извлечение значения:
const polyline =
response.data.routes[0]
.sections[0]
.polyline;
Полученную полилинию можно передать клиентскому приложению для визуализации маршрута.
Для навигационных интерфейсов используются маршрутные действия.
Запрос:
params: {
transportMode: "car",
origin,
destination,
return: "actions,instructions",
apiKey
}
Фрагмент ответа:
{
"actions": [
{
"action": "depart",
"instruction": "Head north"
},
{
"action": "turn",
"instruction": "Turn right"
}
]
}
Извлечение инструкций:
const actions =
response.data.routes[0]
.sections[0]
.actions;
actions.forEach(action => {
console.log(action.instruction);
});
Такие данные часто используются для голосовой навигации и отображения пошагового маршрута.
Маршрут может содержать несколько остановок.
Пример:
params: {
transportMode: "car",
origin: "52.53086,13.38469",
destination: "52.52000,13.40000",
via: [
"52.52500,13.39000",
"52.52300,13.39500"
],
return: "summary",
apiKey
}
При использовании Axios массив параметров может формироваться вручную:
const query = new URLSearchParams();
query.append(
"transportMode",
"car"
);
query.append(
"origin",
origin
);
query.append(
"destination",
destination
);
query.append(
"via",
"52.52500,13.39000"
);
query.append(
"via",
"52.52300,13.39500"
);
В результате маршрут будет проходить через указанные точки.
HERE способен возвращать несколько вариантов движения.
Запрос:
params: {
transportMode: "car",
origin,
destination,
alternatives: 3,
return: "summary",
apiKey
}
Получение списка:
const routes =
response.data.routes;
routes.forEach(route => {
console.log(
route.sections[0]
.summary.length
);
});
Такой механизм позволяет предлагать пользователю разные варианты:
Сервис автоматически использует данные о трафике.
Маршрут рассчитывается с учётом:
Пример:
params: {
transportMode: "car",
origin,
destination,
routingMode: "fast",
return: "summary",
apiKey
}
Основные режимы:
fast
short
Режим fast минимизирует время поездки.
Режим short минимизирует расстояние.
Routing API поддерживает специализированную маршрутизацию грузовиков.
Пример:
params: {
transportMode: "truck",
origin,
destination,
truck[height]: 4,
truck[width]: 2.5,
truck[length]: 12,
truck[grossWeight]: 18000,
return: "summary",
apiKey
}
Учитываются:
Это критически важно для логистических систем.
Маршрутизация поддерживает исключение некоторых типов дорог.
Пример:
params: {
transportMode: "car",
origin,
destination,
avoid: "tollRoad",
return: "summary",
apiKey
}
Возможные варианты:
tollRoad
ferry
tunnel
dirtRoad
controlledAccessHighway
Несколько ограничений:
avoid:
"tollRoad,ferry"
В большинстве проектов создаётся промежуточный REST-сервис.
Пример на Express:
const express = require("express");
const axios = require("axios");
const app = express();
app.get("/route", async (req, res) => {
try {
const response =
await axios.get(
"https://router.hereapi.com/v8/routes",
{
params: {
transportMode: "car",
origin: req.query.origin,
destination:
req.query.destination,
return:
"summary,polyline",
apiKey:
process.env.HERE_API_KEY
}
}
);
res.json(response.data);
} catch (error) {
res.status(500).json({
error: error.message
});
}
});
app.listen(3000);
Преимущества подобного подхода:
При большом количестве запросов полезно хранить результаты в кэше.
Простейший пример:
const cache = new Map();
function buildKey(
origin,
destination
) {
return `${origin}:${destination}`;
}
Проверка кэша:
const key =
buildKey(
origin,
destination
);
if (cache.has(key)) {
return cache.get(key);
}
Сохранение:
cache.set(
key,
response.data
);
В производственных системах обычно применяются:
Серверное приложение должно корректно реагировать на ошибки API.
Типичный шаблон:
try {
const response =
await axios.get(url);
} catch (error) {
if (error.response) {
console.error(
error.response.status
);
console.error(
error.response.data
);
} else {
console.error(
error.message
);
}
}
Наиболее распространённые причины ошибок:
| Код | Причина |
|---|---|
| 400 | Некорректные параметры |
| 401 | Неверный ключ API |
| 403 | Недостаточно прав |
| 404 | Ресурс не найден |
| 429 | Превышен лимит запросов |
| 500 | Ошибка сервера |
Логистические платформы часто рассчитывают сотни или тысячи маршрутов.
Последовательный подход:
for (const item of points) {
const route =
await getRoute(
item.origin,
item.destination
);
}
Параллельный подход:
const promises =
points.map(point =>
getRoute(
point.origin,
point.destination
)
);
const routes =
await Promise.all(promises);
Для предотвращения превышения лимитов обычно применяется ограничение параллелизма.
Пример через пакет p-limit:
const limit = pLimit(5);
const routes =
await Promise.all(
points.map(point =>
limit(() =>
getRoute(
point.origin,
point.destination
)
)
)
);
После получения маршрута сервер обычно отправляет клиенту:
{
"distance": 15000,
"duration": 1200,
"polyline": "BFoz5xJ67i1B..."
}
На клиенте данные используются для:
Разделение вычислений между сервером и клиентом позволяет существенно повысить безопасность приложения, сократить объём передаваемых данных и централизовать работу с сервисами HERE Routing API.