RESTful URI设计和使用spring / java派生类的实现

时间:2012-08-03 12:09:30

标签: java spring rest spring-mvc spring-roo

让我们假设我们将水果作为基类,苹果和香蕉作为派生子类。 我想知道,哪些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

现在,由于Spring已经处理了新对象的创建并设置了所有参数,因此保存对象的方法归结为:

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

我无法弄清楚,如果我在创建表单中设置正确的子句(例如,在调用GET / bananas / new时),应该创建如何告诉spring with subclass:

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 个答案:

答案 0 :(得分:1)

非常重要的是,您不要让您的框架决定您的资源设计。 HTTP不了解基类或子类,只知道资源。忘记Spring框架,你想用资源设计从HTTP / ReSt角度获得什么?

如果您倾向于/fruits/{id}的唯一原因是为了节省您在后端的重复,那么您的设计将受到内部问题的驱动,而不是外部问题。

如果您的banana资源在格式化为JSON而不是apple资源时具有不同的表示(例如新布局,不同属性等),那么,恕我直言,它可能值得用它来处理自己的资源。

一旦做出决定,然后看看如何使用Spring尽可能干净地完成这项任务。