Jad*_*son 13 rest asp.net-web-api
我正在尝试使用ASP.NET Web API为我们的服务设计RESTful Web API.我在弄清楚如何将非CRUD操作路由到正确的控制器操作时遇到了麻烦.让我们假设我的资源是一扇门.我可以用我的门完成所有熟悉的CRUD事情.让我们说我门的模型是:
public class Door
{
public long Id { get; set; }
public string InsideRoomName { get; set; }
public string OutsideRoomName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我可以通过我的web api完成所有标准的CRUD操作:
POST: http://api.contoso.com/v1/doors
GET: http://api.contoso.com/v1/doors
GET: http://api.contoso.com/v1/doors/1234
GET: http://api.contoso.com/v1/doors?InsideRoomName=Cafeteria
PUT: http://api.contoso.com/v1/doors/1234
DELETE: http://api.contoso.com/v1/doors/1234
Run Code Online (Sandbox Code Playgroud)
等等.我遇到麻烦的地方是我需要对我门上的非CRUD动作进行建模.我想针对我的资源建模一个Lock和Unlock动词.阅读ASP.NET文章,指导似乎是在使用自定义操作时切换到RPC样式调用.这给了我一条路:
PUT: http://api.contoso.com/v1/doors/1234/lock
PUT: http://api.contoso.com/v1/doors/1234/unlock
Run Code Online (Sandbox Code Playgroud)
这似乎与REST的精神相冲突,REST旨在指示资源的路径.我想我可以将动词建模为资源:
POST: http://api.contoso.com/v1/doors/1234/lockrequests
POST: http://api.contoso.com/v1/doors/1234/unlockrequests
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我仍然可以使用推荐{controller}/{id}/{action},但似乎我仍然在创建一个混合的RPC/REST API.是否有可能,甚至建议就REST接口而言,将自定义操作放在参数列表中?
PUT: http://api.contoso.com/v1/doors/1234?lock
PUT: http://api.contoso.com/v1/doors/1234?unlock
Run Code Online (Sandbox Code Playgroud)
我可以预见到需要使用查询参数支持此调用,例如:
PUT: http://api.contoso.com/v1/doors?lock&InsideRoomName=Cafeteria
Run Code Online (Sandbox Code Playgroud)
如何创建将此请求映射到我的DoorsController的路由?
public class DoorsController : ApiController
{
public IEnumerable<Doord> Get();
public Door Get(long id);
public void Put(long id, Door door);
public void Post(Door door);
public void Delete(long id);
public void Lock(long id);
public void Unlock(long id);
public void Lock(string InsideRoomName);
}
Run Code Online (Sandbox Code Playgroud)
我可能在这里做了一些关于REST API设计的最佳实践的错误假设,因此任何指导都受到赞赏.
从 RESTful 原则来看,也许最好引入一个“状态”属性来管理那些非 CURD 操作。但我认为不符合真正的生产发展。
对于此类问题的每个答案,看起来您都必须使用解决方法来强制您的 API 设计符合 RESTful。但我担心的是,这真的给用户和开发者带来了方便吗?
让我们看一下Google bloger的API3.0设计:https://developers.google.com/blogger/docs/3.0/reference,它使用lot URL进行非CURD操作。
这很有趣,
POST /blogs/blogId/posts/postId/comments/commentId/spam
Run Code Online (Sandbox Code Playgroud)
描述是
将评论标记为垃圾邮件。这会将评论的状态设置为垃圾邮件,并将其隐藏在默认评论呈现中。
您可以看到,评论有一个状态来指示它是否是垃圾邮件,但它的设计与 JoannaTurban 上面提到的答案不同。
我认为从用户的角度来看,它更方便。不需要关心“status”的结构和枚举值。实际上你可以在“状态”的定义中加入很多属性,比如“isItSpam”,“isItReplied”,“isItPublic”等。如果状态有很多东西,设计就会变得不友好。
在某些业务逻辑需求上,使用易于理解的动词,而不是试图使其完全成为“真正的”RESTful,对于用户和开发人员来说,它的生产力更高。这是我的意见。
要处理该lock/unlock场景,您可以考虑向对象添加State属性Door:
public State State { get; set; }
Run Code Online (Sandbox Code Playgroud)
其中State是可用值的枚举,例如
{
LockedFromOutsideRoom,
LockedFromInsideRoom,
Open
}
Run Code Online (Sandbox Code Playgroud)
澄清:你正在向对象添加状态并不违反宁静的原则,因为每当你打电话给门做某事时,状态就会通过api传递.
然后通过api,您将发送一个PUT/POST请求,以便在每次锁定/解锁时更改门的状态.Post可能会更好,因为它只有一个属性可以更新:
POST: http://api.contoso.com/v1/doors/1234/state
body: {"State":"LockedFromInsideRoom"}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5671 次 |
| 最近记录: |