这里的REST API有很多很好的资源,我已经阅读了很多资源。话虽如此,我需要一些帮助,找出如何正确管理状态。
我有一个REST API,然后是一个访问它的应用程序(通过cURL和AJAX)。虽然不是非常重要,但两者都是用Laravel Framework编写的。应用程序没有任何直接的数据库交互,一切都通过API完成。
使用常见的博客示例(虚构),假设我有一个用户通过OAuth登录,他们想要在博客帖子中添加标签。我需要将以下信息发布到API端点:
- Access Token (User ID is retrieved from this)
- Post ID
- Tag Value
这不是很多的信息,但有一个关键部分:帖子ID 。当我在API端收到这些信息时,我需要做几件事:
1) Does Post with ID #x exist?
2) Can user edit post with ID #x?
3) Does tag already exist? If so grab it. If not, create it.
3) Update post.
现在,我可以在一次通话中发送所有数据并执行所有这些功能 - 或者我可以进行单独调用 - 第一次用于扩展,第二次用于性能。这是一个简单的例子,我的应用程序非常复杂,需要很多不同的角色/权限和层次结构来验证。
基本上归结为这是因为我没有在API端管理任何状态,每次发出请求时我都需要重新验证一系列值,这些值最终会成为几十个查询。我不能依赖正确的值,因为富裕的用户可以轻松地修改隐藏的表单输入,甚至可以设计JSON请求并有效地发布它来破坏数据。
在此OWASP REST security recommendations页面的“保护会话状态”部分下,他们建议在API服务器端缓存 blob 信息并改为传递会话令牌。对我而言,这与REST的“无状态”原则背道而驰,但同样,它更像是一个缓存,因此可以在必要时重新计算。
TL; DR;如何在复杂的“API驱动”应用程序中管理状态,以避免对每个请求和用户可能在任何时候修改并影响应用程序的复杂输入数据集进行数十次重复查询?
答案 0 :(得分:2)
如何在复杂的API驱动状态下管理状态"避免在每个请求上进行数十次重复查询的应用程序 - 所有状态都由URI中保存的数据管理。重复查询在REST
中很常见我认为你面临的问题是你正试图在你的设计中没有任何思考。
事实上,每个请求都必须包含完成该请求所需的所有信息 - 如果您想要成为RESTful'
,则无法解决此问题。我可以看到您的问题所在,因为您不得不一遍又一遍地调用相同的查询。但如果是这种情况,您应该尽可能快地设计这些常见查询。
良好的数据库/ API设计在第一时间会有所帮助,但我会假设您已经这样做了。
您可能忽略的一件事是对数据库进行查询缓存。您的API是RESTful的,您可以根据需要扩展api,但您的数据库服务器可能不需要扩展(除非您有一个MASSIVE API,这非常重要)。因此,对于常见查询,您实际上可以在数据库服务器上实现查询缓存。
这意味着,虽然您反复运行大量相同的查询,但它们只是从数据库缓存中出来。
我正在开发的REST API的一个简单示例是用户凭据。对API的每个单一请求都必须具有随其发送的用户凭据。这意味着对每个请求执行对users表的查询,但我已经在我的数据库上设置了缓存,因此用户详细信息从那里快速恢复。
您的第二点涉及数据验证。您当然应该验证所有用户提交的数据 - 没有例外。
答案 1 :(得分:1)
您不应该在应用程序端执行所有这些操作,API的目的是处理复杂的功能。
调用帖子列表,然后让用户做自己的事情,发布到专门设计用于将标记附加到帖子/posts/{id}/tag
的端点,然后查看响应。如果他们没有权限,您应该获得403
;如果帖子不存在,则应该获得410
。
一定要引入一个ACL,它由初始/me/get
请求返回,这样您就可以检查对它的权限,以防止用户首次进入该页面。
不要为自己过度复杂化,信任API并信任响应。