让我们假设我们将水果作为基类,苹果和香蕉作为派生子类。 我想知道,哪些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,它将代码分离得更多,并且在添加新水果时不需要更改文件。你怎么看,这将是最好的解决方案?
答案 0 :(得分:1)
非常重要的是,您不要让您的框架决定您的资源设计。 HTTP不了解基类或子类,只知道资源。忘记Spring框架,你想用资源设计从HTTP / ReSt角度获得什么?
如果您倾向于/fruits/{id}
的唯一原因是为了节省您在后端的重复,那么您的设计将受到内部问题的驱动,而不是外部问题。
如果您的banana
资源在格式化为JSON而不是apple
资源时具有不同的表示(例如新布局,不同属性等),那么,恕我直言,它可能值得用它来处理自己的资源。
一旦做出决定,然后看看如何使用Spring尽可能干净地完成这项任务。