我正在尝试使用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; }
}
我可以通过我的 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
等等,我遇到问题的地方是需要对我的门进行非CRUD操作建模。我想针对我的资源建模锁定和解锁动作。阅读ASP.NET文章后,指南似乎是在使用自定义操作时切换为RPC风格调用。这给了我一条路径:
PUT: http://api.contoso.com/v1/doors/1234/lock
PUT: http://api.contoso.com/v1/doors/1234/unlock
这似乎与REST的精神相冲突,因为REST旨在使用路径表示资源。我想我可以将动词建模为资源:
POST: http://api.contoso.com/v1/doors/1234/lockrequests
POST: http://api.contoso.com/v1/doors/1234/unlockrequests
在这种情况下,我仍然可以使用推荐的{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
我能预见需要支持此调用的查询参数,例如:
PUT: http://api.contoso.com/v1/doors?lock&InsideRoomName=Cafeteria
我该如何创建路由以将此请求映射到我的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);
}
我可能会在这里做出一些关于REST API设计的最佳实践的错误假设,因此如果有任何指导,将不胜感激。