Clojure "DSL" программирование - PullRequest
       14

Clojure "DSL" программирование

8 голосов
/ 10 октября 2011

Я проектирую REST-сервер JAX-RS с использованием Clojure и RESTEasy .

Насколько я понимаю, приложения, написанные на языках семейства Lisp, больше, чем приложения на "традиционных" императивных языках, созданы как "языки, специфичные для предметной области". Приложение спроектировано снизу вверх как все более и более «усовершенствованные» функции, пока на «верхнем» уровне приложение не станет серией вызовов функций для функций очень высокого уровня.

Я пытаюсь сделать это для моего сервера REST, начиная с классов ресурсов, которые обслуживают запросы URL (GET, POST, PUT, DELETE).

Вот мой первый ресурс:

(ns com.example.server.resources.buildtime
  (:import [javax.ws.rs CookieParam GET Produces Path]
           [javax.ws.rs.core Context Cookie NewCookie Response UriInfo]
           [org.jboss.resteasy.annotations.providers.jaxb Formatted]))

(definterface BuildTime
  (getBuildTime [^javax.ws.rs.core.UriInfo info
                 ^javax.ws.rs.core.Cookie security-cookie]))

(deftype
  ^{Formatted true}
  BuildTimeResource []
  BuildTime
  (^{GET true
     Path "/buildtime"
     Produces ["application/json"]}
    getBuildTime
    [this info security-cookie]
    (.. (Response/ok "20111009") build)))

Этот ресурс возвращает время сборки сервера в виде строки (заключенной в пакет JSON) при вызове по URL-адресу "/ buildtime" с помощью метода GET http.

Я напишу еще много этих классов ресурсов и вложенных методов (большинство классов будет иметь более одного метода), каждый из которых имеет definterface и deftype. Это похоже на идеальное использование для макросов.

Я запрашиваю предложения о том, как это можно сделать в виде DSL. Как можно мыслить в терминах DSL?

1 Ответ

3 голосов
/ 21 марта 2012

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

Ring - это библиотека clojure, которая представляет http-запросы и ответы стандартным способом. Этот стандарт подробно здесь .

Он работает, получая запрос http из любой из множества библиотек (например, jetty, netty, finagle) и переводя его в стандартное представление. Затем он передает запрос обработчику запроса (часто это определяется с помощью Compojure). Затем обработчик возвращает ответ (также определенный в приведенной выше спецификации). Этот ответ переводится по кольцу обратно в форму, понятную моле, нетто и т. Д.

Этот перевод сделан кольцевыми адаптерами. Есть несколько перечисленных здесь , и кольцо поставляется с встроенным адаптером для пристани. Возможно, вы можете использовать один из них в качестве шаблона для создания адаптера RESTEasy. После этого вы можете использовать compojure стандартным способом.

Ring и compojure являются отличными примерами создания DSL. Как и все хорошие DSL, он упрощает создание решений в своей проблемной области (в данном случае HTTP-серверы). Они являются отличным примером того, как мыслить с точки зрения DSL. Если вы изучите их, вы будете на пути к мышлению с точки зрения DSL.

...