2012-08-03 17 views
2

讓我們假設我們有水果作爲基類,蘋果和香蕉作爲派生子類。我想知道,哪些URI約定和實現最有意義。這一個是直截了當:使用spring/java派生類的REST風格的URI設計和實現

GET /fruits - returns list of all fruits 
GET /bananas - returns list of all bananas 
GET /apples - returns list of all apples 
GET /bananas/new - returns form for creating a new banana 

現在,春天已經處理新對象的創建和設置所有它的參數,保存對象的方法歸結爲:

fruit.persist(); // same for bananas and apples 

所以,你會如何設計網址:

POST /fruits - creates a new fruit // as generic URI ... OR 
POST /bananas - creates a new banana // same for apples 

問題,使用通用的方法似乎是,該方法然後將香蕉/蘋果保存爲一個水果代替香蕉/蘋果:

@RequestMapping(value = "/", method = RequestMethod.POST) 
private String saveFruit(@Valid Fruit fruit, Long basketId) { 
    Basket basket = Basket.findBasket(basketId); 
    fruit.setBasket(basket); 
    fruit.persist(); 
} 

我弄不明白,應該創建如何通過子類告訴spring,儘管我在創建表單中設置了正確的值。調用get /香蕉時/新):

uiModel.addAttribute("fruit", new Banana()); 

所以目前我創建了兩個公共方法保存蘋果和香蕉

POST /bananas - create a banana 
POST /apples - create an apple 

實現這樣的:

@RequestMapping(value = "/", method = RequestMethod.POST) 
public String saveBanana(@Valid Banana fruit) { 
    String basketId = this.saveFruit(fruit); 
    return "redirect:/basket/edit/" + basketId; 
} 

不知怎的,這不滿足我的需要,讓事情乾爽簡單。 也因爲編輯的水果時,我想打電話給像

GET /fruits/123/edit - return the edit form of a fruit 

的邏輯,形式字段應該呈現的則是由視圖處理。

也可以考慮調用子類控制器,例如,/bananas/123/edit,它可以將代碼更加分離,並且在添加新水果時不需要更改文件。你認爲什麼是最好的解決方案?

回答

1

這是重要的是,你不要讓你的框架指定你的資源設計。 HTTP不知道任何關於基類或子類,只是資源。忘記Spring框架,你想通過你的資源設計從HTTP/ReSt的角度獲得什麼?

如果您傾向於/fruits/{id}的唯一原因是爲了節省您在後端的重複性,那麼您的設計將從內部問題驅動,而不是外部問題。

如果當作爲JSON比apple資源(例如新的佈局,不同的屬性,等等)格式化您的banana資源有不同的表現,那麼,恕我直言,這可能應該給他們自己的資源來處理。

一旦你做出這個決定,然後看看你如何使用Spring儘可能乾淨地完成這個決定。

+0

皮特,感謝您的建議。我剛開始這樣實現它。每當我有相同的邏輯部分,我現在使用基類控制器的靜態方法(保持乾燥)。 – 2012-08-03 13:07:52