建立Richardson成熟度2级的POST和 GET的RESTful API请看这里:https://www.cnblogs.com/cgzl/p/9047626.html
之前一篇文章介绍了POST和GET,这篇要介绍DELETE, PUT, PATCH.
本文需要用到的代码(右键另存,后缀改为zip): https://images2018.cnblogs.com/blog/986268/201805/986268-20180524161857994-217513181.jpg
DELETE 删除资源这个很简单,以删除City为例:
首先查找Country,没找到就返回404 Not Found;然后查找City,没找到也返回 404 Not Found;如果找到了,删除保存的时候失败,则返回 500 Internal Server Error;如果删除成功,则不需要返回什么内容,返回204 No Content即可。
测试:
如果再次执行该请求的话,不出意外的会返回 404 Not Found:
DELETE并不具有安全性,因为在方法执行后会改变资源(把资源删除了)。
但是DELETE是具有幂等性的,这个你可能会有疑问,我执行多次DELETE后返回的状态码不一样为什么还具有幂等性。
之前我提过幂等性的简单定义,那个定义多少有点模糊,我们再来看一下幂等性定义里关键的一句话:“the side-effects of N > 0 identical requests is the same as for a single request”,意思是多次请求的副作用和单次请求的副作用是一样的。幂等性的核心概念可以理解为:"你可以发送多于一次的同样请求,但是不会对服务器造成额外的改变"。也就是说每次发送了DELETE请求之后,服务器的状态都是一样的。
一起删除主从资源
这种情况也很常见,在删除Country资源的同时,把它的子资源City也删掉。
这个很简单,由于EFCore做了很多工作,就不需要在删除主资源的时候手动去删除它所有的子资源了。
测试:
删除集合资源
DELETE "http://localhost:5000/api/countries",这个请求是合理的。但是确实很少这么做,因为这么做的破坏性还是挺大的。。。
PUT 更新资源
Put应该用来对资源的整体更新。
由于PUT是对资源的整体修改,请求body中应该带着更新对象,所以先建立这个对象:
本身City这个Model就只有两个字段,而id的应该作为路由的参数传递进来,所以在CityUpdateResource里面就不需要id属性了;如果有Id的话,你可能还要与路由参数里的id进行比较,如果不同会带来麻烦,所以这个对象里不带id。
这时你也可以发现CityUpdateResource和CityAddResource所含有的属性是一样的,那么为什么不使用同一个类型呢?因为这两个对象的目的不同,责任不同,一个类只应该有一个责任(SRP)。但是你可以使用某个父类把相同的属性抽取出去,然后分别继承,但是我就不这样做了。
下面看这个PUT的Action方法:
这个方法也很简单,其中有两点需要注意:怎么把传递进来的对象的所有属性值都传递给EFCore的Model?这里使用AutoMapper即可,上面红框的方法就是把第一个参数对象的属性映射到第二个参数对象上。
再有就是应该返回什么?我认为Ok和NoContent都是可以的,如果在Action的方法里某些属性的值是在这里改变的,那么可以使用Ok把最新的对象传递回去;但是如果在Action方法里没有再修改其它属性的值,也就是说更新之后和传递进来的对象的属性值是一样的,那就没有必要再把最新的对象传递回去了,这时就应该使用NoContent。
再看一下Repository里面: