2

假设我们有fruit 作为基类,apple 和banana 作为派生子类。我想知道,哪些 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 应该创建子类:

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,它可以使代码更加解耦,并且在添加新水果时不需要更改文件。你认为什么是最好的解决方案?

4

1 回答 1

1

不要让你的框架支配你的资源设计,这一点非常重要。HTTP 对基类或子类一无所知,只知道资源。忘记 Spring 框架,您想从 HTTP/ReSt 的资源设计角度获得什么?

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

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

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

于 2012-08-03T12:27:09.723 回答