Clojure"DSL"编程

Ral*_*lph 8 dsl clojure

我正在使用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)))
Run Code Online (Sandbox Code Playgroud)

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

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

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

Bri*_*ian 3

如果我要这样做,我想我会从为 RESTEasy 创建一个环形适配器开始。完成此操作后,Compojure 将知道如何以与 RESTEasy 配合使用的方式处理和响应 http 请求。以下是一些可帮助您入门的信息。

Ring 是一个 clojure 库,它以标准方式表示 http 请求和响应。该标准的详细信息请参见此处

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

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

Ring 和 compojure 是如何创建 DSL 的很好的例子。与所有优秀的 DSL 一样,它简化了在其问题域(本例中为 HTTP 服务器)中创建解决方案的过程。它们是如何根据 DSL 进行思考的绝佳示例。如果您研究它们,您将能够顺利地从 DSL 角度进行思考。