具有复杂操作(动词)的RESTful Web服务

4

我正在尝试构建一个网络应用程序,其中后端是完整的RESTful网络服务。也就是说,模型(业务逻辑)可以完全通过HTTP访问。例如:

GET    /api/users/
GET    /api/users/1
POST   /api/users
PUT    /api/users/1
DELETE /api/users/1

如何提供更多不是CRUD(动词/操作)的方法?这是否被视为RPC-api领域?如何正确设计RPC api以在RESTful api之上运行?

例如,我该如何优雅地为用户实现忘记密码的方法?

POST (?) /api/users/1/forgot

应用程序(控制器/视图)将使用https请求(类似HMVC的方式)访问模型和方法。什么是最好的身份验证方式?OAuth,Basic Auth over HTTPs?
虽然这对于以后的可扩展性来说是“最佳实践”,但我是否在过度设计任务?最好只遵循典型的MVC模型并提供非常基本的API?
这个问题主要受到ASP.NET的MVC 4(WebAPI)和NodeJS模块 https://github.com/marak/webservice.js的启发。
提前致谢。
1个回答

1

我最近开始学习REST,在开发新的网络服务时,我认为您考虑的是正确的。

关于自定义动词,你的假设是正确的。REST承认有些操作需要以不同的方式处理,而自定义动词并不违反要求。与服务器通信时应使用POST方法,但通常使用命令语态编写动词。例如,我可能会使用“提醒”等类似的词汇而不是“忘记”。也就是说,应该给出关于要做什么的指示,而不是描述发生了什么事情,而没有明确指示预期的结果。

此外,构建服务的首选方式是将api包含在域名中,并从路径中删除它。我会像这样编写您的特定示例:

POST /users/1/remind HTTP/1.1
Host: api.myservice.example.com

在REST中处理会话有点棘手。最干净的方法可能是在每个请求上使用基本访问身份验证来进行用户名和密码的认证。然而,我相信很少这样做。您应该阅读这个问题(以及它的被接受的答案):OAuth's tokens and sessions in REST

编辑:我还会在您的示例中的GET请求中删除尾随的正斜杠。如果服务真正符合RESTful,则不应从/users//users两个位置访问资源。一个特定的资源应该有一个且仅有一个指向它的URL。带有尾随斜杠的URL实际上与没有尾随斜杠的URL不同。REST推荐删除它,并且RESTful Web服务不应同时接受两者(在GET的情况下意味着响应200 OK),尽管它可以从一个重定向到另一个。否则,可能会导致关于正确URL的混淆,重复缓存,哭泣和咬牙切齿。

编辑2:在Richardson和Ruby的《RESTful Web Services》中,不建议将新动词放在路径中。相反,您可以附加类似于?_method=remind的内容。您可以选择其中一个,但请记住,无论您选择哪种方式,都不应该使用GET处理这些请求,无论如何GET不能更改资源,并且如果用户在历史记录中来回浏览,不应该导致副作用。否则,您可能会多次重新发送密码。请改用POST


谢谢您的回复,Anders。您认为最好一开始就使用典型的MVC方法构建我的应用程序(模型直接与数据库通信),然后再考虑制作api.mysite.com吗?然后将修改模型以直接与API而不是数据库通信。最好将我的模型抽象化,以便在模型中不处理会话/身份验证,对吗? - user1236971
@user1236971 我不是专家,但这是我的看法:单独开发模型有点自相矛盾。您的模型应以结构化方式提供数据,尽可能隐藏底层实现。它还应处理一些基本安全性并隐藏不应公开的内容。例如,您应该能够更改或验证密码,但永远不能检索它(即使是哈希值)。这几乎正是API应该做的事情,您不应该重复编写代码。您的模型就是您的API,尽管您可以跳过JSON转换。 - Anders Sjöqvist
@user1236971 哦,顺便说一下,我不确定你所说的抽象模型是指让它们不涉及身份验证。你打算在哪里实现这个?我会尝试实现模型,以便视图或控制器中的错误永远无法破坏数据,并且这可能涉及进行某些权限检查。但是像我说的那样,会话管理很棘手,我不知道最佳实践。我也遇到了同样的问题。 - Anders Sjöqvist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接