部分字段更新REST API

时间:2016-12-01 17:56:34

标签: java rest updates crud spring-mongo

有这个MongoBean:SuperBean

class SuperBean extends MongoBaseBean{
     private String id;
     private String title;
     private String parent;

     //And getters, setters   
}

需要编写一个更新API,它能够执行部分属性更新。在网络上看到的以及从我的同行那里听到的常见方法是检查请求中的字段为空并且如果不为空则更新。但是如果更新请求是将值更新为Null怎么办?

经过几次讨论,我们提出了三种方法:

  • 设置bean中字段的默认值。因此,如果请求中没有$,则代替非空父字段,将考虑更新。

    class SuperBean extends MongoBaseBean{
     private String id;
     private String title;
     private String parent = "$";
    
     //And getters, setters   
    }
    
  • 让更新API实现接受Map。获取实际的bean,并更新请求映射中存在的所有字段。

    @Post
    public SuperBean updatePartial(Map<String,Object> dataObject) {}
    
  • 让更新API接受包含2个地图的DTO。一个包含旧值,另一个包含新值。这在场景中可能是有利的,其中仅在数据库包含在oldDataObj中发送的值时才发生更新。但这会增加有效载荷的大小。

      class SuperBeanUpdateDTO {
         private Map<String, Object> oldDataObj;
         private Map<String, Object> newDataObject;
         //getters, setters
      }
    
      @Post
      public SuperBean updatePartial(SuperBeanUpdateDTO updateDTO) {}
    

选择其中一种方法应考虑哪些因素?还有另一种更好的方法来解决这个问题吗?

1 个答案:

答案 0 :(得分:1)

In my projects, we usually choose the way that similar with your second way. but not exactly the same.

for example, in your client side, you have a page or a view to modify your profile info, includes name, birthday, gender, although you just modify the name value, when you click save button, it still will send the data to server includes birthday and gender with name field, but just keep its value as old. and the server API will directly update these three values in database, won't check whether its value changed or not.

if you have another page or view to modify other parts of the profile, likes password, it need add a new method in client and a new API in server. the API URL likes PATCH /reset_password, and the sent data should include old_password and new_password field.

PS:
1. we use PUT or PATCH to update a resource, not POST, POST is used to create a new resource. 2. when you update a resource, in the above example, the API likes PATCH /profiles/:id (other's profile) or PATCH /profile (yourself profile), so the sent data doesn't need id field anymore, it includes in your API URL.