Clojure“DSL”编程

时间:2011-10-10 11:35:58

标签: clojure dsl

我正在使用Clojure和RESTEasy设计JAX-RS REST服务器。

我的理解是,用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)))

当使用GET http方法在URL“/ buildtime”调用时,此资源将服务器构建时间作为String(包含在JSON包中)返回。

我将编写更多这些资源类和封闭方法(大多数类将有多个方法),每个方法都有definterfacedeftype。这似乎是宏的完美用法。

我正在征求有关如何以DSL方式完成这项工作的建议。如何根据DSL进行思考?

1 个答案:

答案 0 :(得分:3)

如果我正在进行此操作,我想我会首先为RESTEasy创建一个环形适配器。完成此操作后,Compojure将知道如何以与RESTEasy一起使用的方式处理和响应http请求。这里有一些信息可以帮助您入门。

Ring是一个clojure库,以标准方式表示http请求和响应。此标准详细here

它的工作原理是从各种库(即jetty,netty,finagle)接收一个http请求,并将其转换为标准表示。然后它将请求交给请求处理程序(通常使用Compojure定义)。然后处理程序返回响应(也在上面的规范中定义)。这个响应通过响应转换成码头,网络等可以理解的形式。

此转换由环形适配器完成。有一些列出here,并且ring附带了一个内置jetty的适配器。也许您可以使用其中一个作为模板来创建RESTEasy适配器。完成后,您可以以标准方式使用compojure。

Ring和compojure是如何创建DSL的很好的例子。像所有优秀的DSL一样,它简化了在其问题域(在这种情况下为HTTP服务器)中创建解决方案。它们是如何根据DSL思考的很好的例子。如果你研究它们,你就会在思考DSL方面做得很好。