【发布时间】:2011-10-10 11:35:58
【问题描述】:
我正在使用 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” 处调用此资源时,此资源会以字符串形式(包含在 JSON 包中)返回服务器构建时间。
我将编写更多这些资源类和封闭的方法(大多数类将有多个方法),每个都有definterface 和deftype。这似乎是宏的完美用途。
我正在征求有关如何将其作为 DSL 完成的建议。如何从 DSL 的角度进行思考?
【问题讨论】:
-
首先:停止思考“类”。它已经是一个 DSL,已经有点潜在的外来语义,你可能不想在最终的 DSL 中看到。从正式指定问题开始。列出实体,在它们之上定义一个代数,它会自然地结晶到你的 DSL 中。只有这样,您才必须开始考虑实施。
-
你知道compojure吗? github.com/weavejester/compojure 它提供了一种 DSL,与您似乎想到的没有什么不同。我还发现这篇文章pragprog.com/magazines/2011-07/growing-a-dsl-with-clojure 有助于进入“dsl 模式”。但是想出一个好的 DSL 似乎不是一件容易的事……
-
@Paul:我考虑过 Compojure。我们已经有一个用 RESTEasy/Java 编写的大型 REST 服务器。如果我使用我们熟悉的框架,将一个新的基于 Clojure 的新框架轻松融入组织将减少阻力。此外,JAX-RS 还有一些非常好的特性。