2011-10-10 13 views
8

Sto progettando un server REST JAX-RS usando Clojure e RESTEasy.Programmazione Clojure "DSL"

È a mia conoscenza che le applicazioni scritte nelle lingue della famiglia Lisp sono, più di quelle in lingue "tradizionali" imperative, costruite come "lingue specifiche del dominio". L'applicazione è progettata dal basso verso l'alto come funzioni sempre più "raffinate" fino a quando, al livello "top", l'applicazione diventa una serie di chiamate di funzione a funzioni di altissimo livello.

Sto provando a farlo per il mio server REST, iniziando con le classi di risorse che soddisfano le richieste URL (GET, POST, PUT, DELETE).

Qui è la mia prima risorsa:

(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))) 

Questa risorsa restituisce il tempo di costruzione server come una stringa (racchiusa in un pacchetto di JSON) quando viene chiamato presso l'URL "/ buildtime" con il metodo HTTP GET.

Scriverò molte più di queste classi di risorse e metodi chiusi (la maggior parte delle classi avrà più di un metodo), ognuna con un definterface e un deftype. Questo sembra un uso perfetto per le macro.

Sto sollecitando suggerimenti su come questo potrebbe essere fatto come DSL. Come si fa a pensare in termini di DSL?

+3

Per cominciare: smettere di pensare in termini di "classi". È già un DSL, già un po 'di semantica potenzialmente aliena che potresti non voler vedere nel DSL finale. Inizia con la specifica del problema formalmente. Elenca le entità, definisci un'algebra su di esse e si cristallizzerà naturalmente nel tuo DSL. Solo allora devi iniziare a pensare all'implementazione. –

+1

Sai di compojure? https://github.com/weavejester/compojure Fornisce un DSL non dissimile da quello che sembra avere in mente. Ho trovato anche questo articolo http://pragprog.com/magazines/2011-07/growing-a-dsl-with-clojure utile per entrare in 'dsl-mode'. Ma trovare un buon DSL non sembra un compito facile ... – Paul

+0

@Paul: ho considerato Compojure. Abbiamo già un grande server REST scritto in RESTEasy/Java. Facilitare una nuova organizzazione basata sul Clojure nell'organizzazione otterrà meno resistenza se utilizzo un framework con il quale ci è familiare. Inoltre, JAX-RS ha alcune caratteristiche molto carine. – Ralph

risposta

3

Se dovessi intraprendere questa operazione, penso che inizierei creando un adattatore ad anello per RESTEasy. Dopo averlo fatto, Compojure saprà come gestire e rispondere alle richieste http in un modo che funzioni con RESTEasy. Ecco alcune informazioni per aiutarti a iniziare.

Ring è una libreria di clojure che rappresenta le richieste e le risposte http in modo standard. Questo standard è dettagliato here.

Funziona ricevendo una richiesta http da una qualsiasi varietà di librerie (ad es., Jetty, netty, finagle) e traducendola nella rappresentazione standard. Invia quindi la richiesta a un gestore richieste (spesso questo viene definito utilizzando Compojure). Il gestore restituisce quindi una risposta (definita anche nella specifica precedente). Questa risposta è tradotta dall'anello in una forma che può comprendere il molo, la banchina, ecc.

Questa traduzione viene eseguita da adattatori ad anello. Ce ne sono alcuni elencati here e ring viene fornito con un adattatore per il molo integrato. Forse puoi usarne uno come modello per la creazione di un adattatore RESTEasy. Dopo averlo fatto, puoi usare Compojure nel modo standard.

Ring and compojure sono ottimi esempi di come creare una DSL. Come tutti i buoni DSL, semplifica la creazione di soluzioni nel suo dominio problematico (server HTTP in questo caso). Sono ottimi esempi di come pensare in termini di DSL. Se li studi, sarai sulla buona strada per pensare in termini di DSL.