DSL для реализации бизнес-правил для маршрутизации и обработки сервиса REST
Я надеюсь что Combinator parsers
, ( http://debasishg.blogspot.com/2008/04/external-dsls-made-easy-with-scala.html), будет работать над проектом для обработки правил маршрутизации для службы REST, которая реализована с помощью Scalatra
( http://tutorialbin.com/tutorials/80408/infoq-scalatra-a-sinatra-like-web-framework-for-scala).
Эта служба REST должна выступать в качестве прокси, чтобы внешние приложения могли получать доступ к службам в брандмауэре, поскольку у нее будут дополнительные уровни безопасности, которые можно настроить в соответствии с бизнес-требованиями каждой службы REST.
Таким образом, если человек хочет получить доступ к своему расписанию занятий, безопасность будет ниже, чем если бы вы захотели взглянуть на стенограмму кого-то.
Я хотел бы, чтобы правила о том, куда идти, чтобы получить информацию и как ее вернуть, а также о том, какая безопасность необходима, в DSL.
Но первая проблема заключается в том, как динамически изменять правила маршрутизации для службы REST на основе DSL, поскольку я пытаюсь создать среду, которая не требует большой перекомпиляции для добавления новых правил, а просто пишет соответствующие сценарии и просто пусть это будет обработано.
Итак, можно ли реализовать DSL с помощью Combinator Parser в Scala, который позволит JAX-RS ( http://download.oracle.com/javaee/6/tutorial/doc/giepu.html) динамически изменять маршрутизацию?
ОБНОВИТЬ:
Я еще не разработал язык, но вот что я пытаюсь сделать:
route /transcript using action GET to
http://inside.com/transcript/{firstparam}/2011/{secondparam}
return json encrypt with public key from /mnt/publickey.txt
for /education_cost using action GET combine http://combine.com/SOAP/costeducate with
http://combine.com/education_benefit/2010 with
http://combine.com/education_benefit/2011 return html
Это две возможные идеи, когда правила запроса транскрипта отправляются на другой сайт, например в брандмауэр, а данные шифруются и возвращаются.
Второй будет более сложным в том смысле, что результаты SOAP и двух запросов REST будут объединены, и для их объединения потребуются дополнительные команды, но идея состоит в том, чтобы поместить все это в файлы, которые могут быть проанализированы на лету.
Если бы я использовал Groovy, то для маршрутизации можно было бы сгенерировать несколько новых классов, которые бы убрали некоторые скачки производительности, но я думаю, что использование Scala будет лучшим выбором, даже если я получу удар по производительности.
Я надеюсь сделать структуру более удобной для обслуживания, чтобы новые правила маршрутизации могли писать люди, которые не знают ООП или функциональных языков, но спецификации могут быть написаны с использованием Specs
( http://code.google.com/p/specs/), чтобы функциональная сторона была уверена, что их требования проверяются на регулярной основе.
ОБНОВЛЕНИЕ 2:
Когда я начинаю работать над дизайном, я могу интуитивно понять некоторые варианты, но не знаю почему. Сегодня я понял, что причина того, что Groovy может быть лучше для этого, состоит в том, что я мог бы затем генерировать классы для маршрутизации, используя метапрограммирование ( http://www.justinspradlin.com/programming/groovy-metaprogramming-adding-behavior-dynamically/), тогда я смогу использовать Scala или Groovy для динамического использования сгенерированной маршрутизации. Я не уверен, как заставить Scala генерировать классы, если они еще не существуют.
В Groovy, а также в некоторых других языках, как показано здесь ( http://langexplr.blogspot.com/2008/02/handling-call-to-missing-method-in.html), если метод отсутствует, вы можете динамически сгенерируйте метод, и он отныне будет существовать, поэтому он будет отсутствовать один раз.
Похоже, что я должен смешивать Groovy с Java, чтобы сделать эту работу, но в результате может получиться так, что часть кода на Scala, а другая на Java, предназначена для маршрутизации служб REST.
1 ответ
Разделив вопрос на две части:
Можно ли реализовать DSL с помощью Combinator Parser
Да. Есть вещи, которые не могут быть реализованы с помощью парсера-комбинатора или даже других видов парсера. Например, сам Perl не может быть проанализирован (он должен быть оценен). Парсеры комбинатора также не особенно хороши для сложных языков (таких как Scala - его компилятор не основан на парсерах комбинатора), или если вам требуется максимальная производительность (например, компиляторы, используемые для компиляции сотен тысяч строк кода).
Однако, если вы планируете пойти на такие крайности, выбор парсера не будет вашей главной проблемой. Для DSL средней сложности они подойдут.
это позволит JAX-RS динамически менять маршрут
Ну, я не знаю JAX-RS, но если с ним можно сделать динамически измененную маршрутизацию, то синтаксические анализаторы комбинаторов смогут предоставить любой необходимый ввод.
РЕДАКТИРОВАТЬ
Видя твой пример, я думаю, что парсер-комбинаторов вполне достаточно. Исходя из их результатов, я ожидаю, что вы можете динамически создавать связки BlueEyes - я не использовал BlueEyes, поэтому я не уверен, насколько они динамичны.
Другой альтернативой будет пойти с лифтом. Связующие лифта являются частичными функциями, и их можно комбинировать всеми обычными способами - f1 orElse f2
, f1 andThen f2
и т. д. Сначала я не предлагал этого, поскольку он чаще всего используется с сессиями, но у него есть модель RESTful, которая, как мне кажется, не имеет состояния.
Я не знаю Скалатру, поэтому я не знаю, будет ли она адаптирована к этому или нет.