Маршруты на JavaScript
Ответы на запросы к моку на JavaScript до его остальных маршрутов и спецификации, с состоянием, которое хранится, пока мок работает.
Маршруты, созданные вручную, и спецификация отвечают заранее записанными ответами. Иногда моку нужно больше: запомнить заказ, который только что сделал клиент, вычислить ответ или упасть на третьем вызове. Маршруты на JavaScript — это небольшие обработчики, которые отвечают на запросы к моку первыми. Их переменные живут, пока мок работает, поэтому между запросами они могут хранить состояние. Всё, что маршрут не обработал, идёт дальше: к маршрутам мока, созданным вручную, а затем к его спецификации.
Написание маршрутов
Откройте мок на странице «Моки» и прокрутите до карточки Маршруты на JavaScript. Напишите маршруты в редакторе и нажмите Сохранить маршруты. Вернуть возвращает то, что было сохранено.

В этом примере, для мока спецификации Alpenglow, хранятся заказы, которые делает клиент, и возвращаются по ID:
let orders = []
mock.post("/orders", (req, res) => {
const order = { id: "ord_" + (orders.length + 1), status: "pending", ...req.json() }
orders.push(order)
res.status(201).header("Location", "/v1/orders/" + order.id).json(order)
})
mock.get("/orders/:id", (req, res) => {
const order = orders.find(o => o.id === req.params.id)
return order ?? res.status(404).json({ error: "no such order" })
})После сохранения карточка перечисляет маршруты, которые зарегистрировал скрипт
(Running: POST /orders, GET /orders/:id), или оранжевым — почему скрипт не загрузился. Маршруты хранятся в
mocks/<name>.js рядом с настройками мока, так что вместе с рабочим пространством попадают в Git.
Когда выполняются маршруты
- Маршруты на JavaScript отвечают первыми, до маршрутов, созданных вручную, и спецификации. Отвечает первый маршрут, у которого совпали метод и путь.
- Пути отсчитываются от пути сервера спецификации, если мок обслуживает спецификацию: пишите
/orders, а не/v1/orders. - Маршрут, который ничего не задаёт и ничего не возвращает, передаёт запрос дальше — маршрутам, созданным вручную, и спецификации, которые отвечают как обычно. Так можно обрабатывать лишь некоторые запросы, например с определённым параметром запроса.
- Скрипт выполняется один раз, когда мок запускается. Его переменные верхнего уровня и объект
stateживут, пока мок не остановится. - Сохранение перезапускает маршруты с чистым состоянием. Изменения спецификации, маршрутов, созданных вручную, или настроек мока его сохраняют.
- Запросы обрабатываются по одному, поэтому состояние остаётся согласованным.
Журнал мока помечает каждый запрос, обработанный маршрутом, именем маршрута: наведите на него
указатель, чтобы увидеть Ответил этот маршрут или Передан дальше этим маршрутом (маршрутам, созданным вручную,
или спецификации). То, что маршрут выводит через console.log, появляется в журнале под запросом.
API маршрутов
Маршруты регистрируются через mock и метод:
| Функция | Соответствует |
|---|---|
mock.get(path, handler) | GET |
mock.post, mock.put, mock.patch, mock.delete, mock.head, mock.options | Этому методу |
mock.any(path, handler) | Любому методу |
В пути :name соответствует одному сегменту и помещает его в req.params.name; * соответствует остатку пути.
Обработчик получает req и res:
req | Что содержит |
|---|---|
req.method | Метод, заглавными буквами. |
req.path | Путь, отсчитываемый от пути сервера спецификации. |
req.params | Сегменты пути :name. |
req.query | Параметры запроса, для каждого имени — последнее значение. |
req.headers | Заголовки, с именами в нижнем регистре. |
req.body | Тело как текст. |
req.json() | Тело, разобранное как JSON, или null, если тела нет. |
res | Что делает |
|---|---|
res.status(code) | Задаёт статус. По умолчанию 200. |
res.header(name, value) | Добавляет заголовок. |
res.json(value) | Отправляет значение как JSON с Content-Type: application/json, если вы не задали другой. |
res.send(text) | Отправляет текст с Content-Type: text/plain; charset=utf-8, если вы не задали другой. |
Каждая функция res возвращает res, поэтому вызовы можно объединять в цепочку: res.status(201).json(order).
Значение, которое возвращает обработчик, отправляется как JSON, так что return order — то же, что res.json(order).
Обработчики могут быть async.
state (он же mock.state) — объект, который сохраняется между запросами, для того, что вам не хочется держать в
собственной переменной:
mock.get("/me", (req, res) => {
state.calls = (state.calls ?? 0) + 1
if (state.calls % 3 === 0) return res.status(503).json({ error: "try again" })
// Nothing set: the routes made by hand or the spec answer this request.
})Ограничения
Маршруты выполняются в той же песочнице, что и скрипты запросов, а не в Node: без
файловой системы и без сети. На каждый запрос JavaScript может работать 2 секунды, и ещё 2 секунды у скрипта есть на
запуск. Обработчик, который выбрасывает исключение, отвечает 500 с текстом ошибки, она видна и в журнале.
Доверие к маршрутам
Маршруты — это код, который выполняется на вашем Mac, поэтому для них то же правило, что и для скриптов запросов. Маршруты, которые вы пишете и сохраняете в Echolot, выполняются. Маршруты, пришедшие извне — через Git, импорт или другое приложение, которое правит файл, — нет: карточка сообщает Эти скрипты пришли не из Echolot, и мок не запускается, пока вы не прочитаете их и не нажмёте Доверять скриптам. Если они снова изменятся вне Echolot, Echolot спросит ещё раз.
Агенты могут читать маршруты мока, но никогда не пишут их.
Из командной строки
echolot mock -w <workspace> <mock> запускает мок рабочего пространства со всеми его маршрутами; --routes <file>
запускает маршруты на JavaScript из другого файла, в том числе вместе с файлом спецификации. См.
echolot mock.
Маршруты и тестовые данные
Создание маршрутов мока вручную: ответы в JSON, XML или текстом, тестовые данные, которые меняются при каждом запросе, правила выбора ответа и запросы, созданные из маршрутов.
Сценарии
Соединяйте сохранённые запросы, MCP-серверы и инструменты Echolot в небольшие программы на холсте и запускайте их вручную, по расписанию, по вебхуку или как инструмент для агентов.
