2011-06-18 87 views
1

我希望Combinator parsershttp://debasishg.blogspot.com/2008/04/external-dsls-made-easy-with-scala.html)將用於設計來處理用Scalatrahttp://tutorialbin.com/tutorials/80408/infoq-scalatra-a-sinatra-like-web-framework-for-scala)實現的REST服務的路由規則。DSL實現REST服務路由和處理的業務規則

這REST服務是作爲一個代理,以便外部應用程序可以讓防火牆內獲得服務,因爲這將有一個可定製每個REST服務的業務要求額外的安全層。

所以,如果一個人想要訪問他們的上課時間會有比,如果你想看看別人的成績單安全更少。

我想爲去哪裏實際獲得的信息,以及如何退貨,以及所需要的安全性,在DSL的規則。

但是,第一個問題是如何動態更改基於DSL的REST服務的路由規則,因爲我試圖創建一個不需要大量重新編譯來添加新規則的框架,但只需編寫適當的腳本並讓它被處理。所以,可以使用Scala中的Combinator Parser來實現DSL,這將允許JAX-RS(http://download.oracle.com/javaee/6/tutorial/doc/giepu.html)具有動態更改路由嗎?

UPDATE:

我還沒有設計語言還沒有,但是這是我想做的事:

route /transcript using action GET to 
http://inside.com/transcript/{firstparam}/2011/{secondparam} 
return json encrypt with public key from /mnt/publickey.txt 

for /education_cost using action GET combine http://combine.com/SOAP/costeducate with 
http://combine.com/education_benefit/2010 with 
http://combine.com/education_benefit/2011 return html 

這是兩種可能的想法,其中對於一個請求規則轉錄本被髮送到不同的站點,例如防火牆內,數據被加密並返回。

第二種情況會更加複雜,因爲SOAP和兩個REST請求的結果將會結合起來,並且需要有關於如何組合這些結果的附加命令,但是想法是將所有這些結合到文件中可以即時解析。

如果我使用Groovy,那麼可能會爲路由生成一些新類,這會刪除一些性能命中,但我認爲使用Scala將是最好的選擇,即使我執行了性能命中。

我希望做一個框架,更容易維護,以便新的路由規則可以由人不知道任何OOP或功能性語言編寫,但規格可以使用寫入Specshttp://code.google.com/p/specs/),這樣的功能方可以確定他們的要求是經常測試的。

更新2:

當我開始在設計工作,我可以直觀地瞭解一些選擇,但是不知道爲什麼。今天,我意識到Groovy可能是更好的解決方案的原因是,我可以使用元編程(http://www.justinspradlin.com/programming/groovy-metaprogramming-adding-behavior-dynamically/)生成路由類,然後我將能夠使用Scala或Groovy動態使用產生。我不確定如何讓Scala生成類,如果它們不存在的話。

在Groovy以及其他一些語言中,如下所示(http://langexplr.blogspot.com/2008/02/handling-call-to-missing-method-in.html)如果缺少一個方法,您可以動態生成該方法,並且它將從此存在,因此它將會丟失一次。

似乎我應該將Groovy與Java混合來完成這項工作,但結果可能是某些代碼在Scala中,有些在Java中,用於REST服務的路由。

+0

你不需要生成類:簡單的函數就可以了。 –

+0

@Daniel C. Sobral - 正如我的問題所述,如果有人想創建/ transcript或/ education_cost端點,我不希望他們必須進入並重新編譯服務器代碼,而是編寫腳本並獲得它處理「神奇」。那麼一個簡單的函數如何將代碼放入端點的路由中。這是我的鬥爭,如何純粹在Scala內部完成這項工作,因爲我認爲我可以通過混合Scala和Groovy來實現,但現在變得更加複雜。 –

+0

我只是說可以用簡單的功能來完成。使用解析器,您可以獲得將DSL轉換爲AST的功能。然後你可以將它轉換成一個'Plan'(來自Unfiltered),它只是一個將請求轉換爲響應的函數的包裝器。它都不需要定義新的類。 –

回答

3

拆分爲兩個部分問題:

可以在DSL使用Combinator的解析器

是實施。有些東西不能用組合器解析器實現,甚至不能用其他類型的解析器實現。例如,Perl本身不能被解析(它必須被評估)。而組合語法分析器對於複雜語言(如Scala--它的編譯器不是基於combinator分析器)或者如果您要求最高性能(例如用於編譯數十萬行代碼的編譯器),也不是特別好。

但是,如果你打算走到這樣的極端,選擇解析器不會是你的主要問題。對於平均複雜度的DSL,他們會做得很好。

,將允許有動態變化的JAX-RS路由

好了,我不知道JAX-RS,但如果動態地改變路由可以用它來完成,然後組合子解析器會能夠提供任何需要的輸入。

編輯

看到你的榜樣,我覺得解析器組合肯定是不夠的。從他們的結果中,我期望你可以動態地創建BlueEyes綁定器 - 我沒有使用BlueEyes,所以我不確定它們是多麼動態。

另一種方法是使用Lift。 Lift的活頁夾是部分功能,它們可以以所有常用方式組合 - f1 orElse f2f1 andThen f2等。我並沒有首先提出它,因爲它最常用於會話,但它有一個RESTful模型,我認爲,是無狀態的。

我不知道Scalatra,所以我不知道它是否適應這個或不是。

+0

謝謝。我知道如何用比較器編寫DSL,但是後來在設計中卡住了我可以擁有一個REST服務並根據第一個參數進行更改的事實,但是我不知道我是否會走錯路。例如,這可能比使用Groovy更容易實現。 –

+0

@James你看過[Unfiltered](http://unfiltered.databinder.net/Unfiltered.html)還是[BlueEyes](https://github.com/jdegoes/blueeyes)?如果問題只是對REST路徑進行解碼,他們會很好地完成。 (PS:上面未經​​過濾和BlueEyes是鏈接) –

+0

問題不僅在於解碼,因爲我不想創建端點,我希望根據控制腳本中的內容動態創建端點,正如我今天更詳細解釋的,但這些看起來很有趣,所以謝謝。 –