我正在使用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包中)返回。
我将编写更多这些资源类和封闭方法(大多数类将有多个方法),每个方法都有definterface
和deftype
。这似乎是宏的完美用法。
我正在征求有关如何以DSL方式完成这项工作的建议。如何根据DSL进行思考?
答案 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方面做得很好。