WiremockJs: как создать свой скриптовый язык для WireMock и зачем это нужно

Создание собственного языка программирования — задача, которая обычно ассоциируется с крупными корпорациями и десятилетиями работы. Но, как показывает свежая статья на Habr, энтузиаст может сделать это в одиночку и для вполне практичной цели. Автор рассказал, как разработал WiremockJs — скриптовый я

WiremockJs: как создать свой скриптовый язык для WireMock и зачем это нужно

Создание собственного языка программирования — задача, которая обычно ассоциируется с крупными корпорациями и десятилетиями работы. Но, как показывает свежая статья на Habr, энтузиаст может сделать это в одиночку и для вполне практичной цели. Автор рассказал, как разработал WiremockJs — скриптовый язык для WireMock, популярного инструмента для мокирования HTTP-сервисов. Проект прошёл путь от идеи до рабочего прототипа, и в процессе автору пришлось решать нетривиальные задачи: проектировать грамматику, разбираться с ANTLR и осознанно отказаться от JavaScript в пользу собственного диалекта.

WireMock используется разработчиками для имитации поведения внешних сервисов при тестировании. Однако его встроенные средства для описания сценариев часто оказываются недостаточно гибкими. Автор статьи столкнулся с этой проблемой и решил, что единственный способ решить её — создать язык, который позволит писать логику моков более выразительно и удобно. Так родился WiremockJs.

Зачем понадобился собственный язык

Идея создать свой язык возникла не от хорошей жизни. Автор объясняет, что стандартные возможности WireMock для динамических ответов ограничены: приходится использовать шаблоны или писать код на Java, что громоздко и неудобно. Ему хотелось иметь простой и лаконичный способ описывать сценарии, например, возвращать разные ответы в зависимости от параметров запроса, имитировать задержки или генерировать данные.

Первоначально автор рассматривал вариант использования JavaScript как встраиваемого скриптового языка — это популярное решение, которое применяется во многих инструментах. Однако от этой идеи пришлось отказаться. JavaScript слишком сложен для парсинга и выполнения в контексте WireMock, а его синтаксис избыточен для задач, которые нужно решать при мокировании. Вместо этого автор решил спроектировать собственный упрощённый диалект, который включал бы только необходимые конструкции и был бы лёгким для изучения.

Такой подход имеет свои преимущества: язык можно сделать максимально приближенным к предметной области, исключив всё лишнее. Но это и серьёзный вызов — нужно продумать грамматику, реализовать парсер и интерпретатор, обеспечить обработку ошибок и документацию.

Как проектировалась грамматика и какие инструменты использовались

Проектирование грамматики — ключевой этап в создании любого языка. Автор использовал ANTLR — мощный генератор парсеров, который позволяет описывать грамматику в виде формальных правил и автоматически создавать парсер на целевом языке программирования. Это стандартный инструмент для подобных задач, и он хорошо зарекомендовал себя в сообществе.

В статье автор делится деталями: как он определял синтаксис, какие конструкции включил в язык, как решал проблемы приоритетов операторов и вложенности выражений. Он упоминает, что столкнулся с ограничениями ANTLR, связанными с левой рекурсией, и как обходил их. Также он рассказывает о боли, которую доставляет отладка парсеров, и о том, как тестировал грамматику на реальных примерах.

В итоге WiremockJs получил простой синтаксис, напоминающий смесь JavaScript и Python: есть переменные, условия, циклы, функции, но всё это в минимальном объёме. Главный акцент — на работе с HTTP-запросами и ответами: можно легко извлекать параметры, заголовки, тело запроса и формировать ответ.

Какие конструкции поддерживает WiremockJs и как они упрощают мокирование

WiremockJs включает в себя базовые конструкции, необходимые для описания логики моков: переменные, условные операторы, циклы и функции. Однако в отличие от полноценных языков, здесь нет классов, наследования или асинхронности. Это сознательное упрощение, которое делает интерпретатор быстрым и надёжным. Например, для получения значения заголовка запроса достаточно написать request.headers['Content-Type'], и это сразу возвращает строку, без лишних проверок на null. Такой подход экономит время и снижает вероятность ошибок при написании тестовых сценариев.

Чем WiremockJs отличается от JavaScript и других решений

Главное отличие — простота и специализация. JavaScript — это полноценный язык с огромным количеством возможностей, но для задач мокирования большинство из них не нужны. WiremockJs сфокусирован на узкой области, поэтому его синтаксис чище и понятнее. Например, для получения значения заголовка запроса в WiremockJs достаточно написать request.headers['Content-Type'], тогда как в JavaScript пришлось бы использовать цепочки вызовов и проверки на null.

Кроме того, автор отказался от некоторых возможностей, которые усложняют реализацию: нет классов, нет прототипного наследования, нет асинхронности. Это сознательное упрощение, которое позволяет сделать интерпретатор быстрым и надёжным. Вместо этого язык предоставляет встроенные функции для работы с JSON, регулярными выражениями и датами.

Важно отметить, что WiremockJs — это не замена JavaScript, а альтернатива для конкретного сценария использования. Автор подчёркивает, что если вам нужна полная мощь языка, лучше использовать JavaScript, но если вы хотите писать моки быстро и без лишней возни, WiremockJs может стать отличным выбором.

Кого затронет этот проект и как его использовать

Основная аудитория WiremockJs — разработчики, которые используют WireMock в своих проектах. Это прежде всего Java-разработчики, занимающиеся микросервисами и тестированием интеграций. Для них новый язык может упростить написание тестовых сценариев и сделать их более читаемыми.

Практическая польза очевидна: вместо того чтобы писать громоздкие Java-классы для каждого мока, можно описать логику на WiremockJs прямо в конфигурации. Это сокращает время разработки и снижает порог входа для новых членов команды. Кроме того, язык позволяет легко имитировать различные сценарии, включая ошибки, таймауты и нестандартные форматы данных.

В статье автор приводит примеры, как использовать WiremockJs в реальных проектах, и показывает, как подключить его к WireMock. Он обещает, что в будущем планирует добавить поддержку более сложных конструкций и улучшить документацию.

Как начать использовать WiremockJs в своём проекте уже сегодня

Чтобы начать использовать WiremockJs, достаточно скачать библиотеку с GitHub и подключить её к вашему проекту. Автор предоставляет подробную инструкцию по установке и настройке. Основная идея — вы описываете сценарий на WiremockJs в отдельном файле, а затем указываете путь к этому файлу в конфигурации WireMock. Всё остальное берёт на себя интерпретатор. Это позволяет быстро внедрить язык в существующую инфраструктуру без серьёзных изменений.

Что будет дальше с WiremockJs

Сейчас WiremockJs находится в стадии прототипа, но автор активно развивает проект. Он планирует добавить больше встроенных функций, улучшить обработку ошибок и, возможно, создать онлайн-песочницу для экспериментов. Также он рассматривает возможность интеграции с другими инструментами мокирования, чтобы расширить аудиторию.

Будущее проекта зависит от интереса сообщества. Если разработчики оценят удобство языка, он может стать стандартом де-факто для описания моков в WireMock. Однако пока это нишевое решение, и автору предстоит проделать большую работу, чтобы довести его до промышленного уровня.

Итог

WiremockJs — это пример того, как индивидуальная инициатива может решить реальную проблему в разработке. Автор показал, что создание языка программирования — это не только удел гигантов, но и доступная задача для энтузиаста с хорошим знанием инструментов. Его опыт будет полезен всем, кто задумывается о создании собственных DSL или просто хочет лучше понять, как работают парсеры и интерпретаторы.

Если вы используете WireMock и чувствуете ограничения его стандартных возможностей, стоит присмотреться к WiremockJs. Возможно, это именно то, что вам не хватало для комфортной работы с моками. Попробуйте — и вы увидите, как просто можно описывать сложные сценарии тестирования.