是否有必要为移动应用程序构建单独的 API 端点以访问 Rails Web 应用程序?

是否有必要为移动应用程序构建单独的 API 端点以访问 Rails Web 应用程序?

问题描述:

我有一个在 Ruby on Rails 4 中实现的网络应用,需要一个 Android 原生应用,我对移动开发非常陌生.

I have a web app implemented in Ruby on Rails 4, need an Android native app for it, I am really new to mobile development.

对于在这种情况下移动网络架构应该是什么样子,我有点困惑.我在网上做了一些研究,似乎有几种方法可以做到这一点,但我仍然有一些我无法找到答案的问题.预先感谢所有指点.

I am a bit confused as to what the mobile-web architecture should look like in this case. I've done some research online, there seems to be a few ways of doing this, but I still have some questions that I haven't been able to find answers for. Thanks in advance for all pointers.

1) 我真的需要为移动应用程序提供单独的 API 吗?使用带有 respond_to format.json 的 Rails 应用程序的现有控制器有什么问题?

1) do I really need a separate API for the mobile app? what are the issues in using my Rails app's existing controllers with respond_to format.json?

2) 我看过一些在线示例,这些示例建议在 Rails 应用程序中使用单独的 API 命名空间来处理移动请求,例如 class Api::ApiController <ActionController::Base 为新控制器,然后在 routes.rb 中添加 namespace :api do.使用这种方法,是否意味着我需要在这个新的命名空间中为移动设备复制相当多的控制器功能?

2) I've seen some online examples that suggest using an separate API namespace in the Rails app to serve mobile requests, e.g class Api::ApiController < ActionController::Base for the new controller, then add namespace :api do in routes.rb. With this approach, doesn't it imply that I'll need to duplicate quite a bit of my controller functionality in this new namespace just for mobile?

3) 关于身份验证,很多例子都建议使用令牌身份验证,内置的Rails会话管理框架对移动应用程序不够好?还是因为会话 cookie 在移动应用中的工作方式完全不同?

3) Regarding authentication, many examples suggest using token authentication, is the built-in Rails sessions management framework not good enough for mobile apps? or is it because session cookies work completely differently in a mobile app?

珍惜你的时间.

这不是必需的,但正如您所说,它被认为是最佳实践.

It is not necessary, but it is, like you said, considered a best practice.

1+2) 乍一看,使用带有 response_to/respond_with 逻辑的相同控制器是一个不错的主意.但是,根据我的经验,我可以说,总会有一天 API 代码开始与 HTML 客户端代码不同.移动客户端可能有不同的用户界面,很自然,它会期望以另一种方式使用您的数据,就像您的 Web 客户端一样.Web 客户端专门用于一种用例,其中 API 应该更通用,允许多种消费方式.

1+2) Having same controllers with respond_to/respond_with logic is a nice idea at first sight. But, from my experience, I can say, there always comes a day where API code start to differ with HTML client code. The mobile client might have a different UI and it is just natural that it will expect to consume your data another way as your web client does. The web client is specialized to one use case where an API should be more generic allowing multiple consuming ways.

会出现的第二个问题是,您不能依赖移动用户始终拥有最新的应用程序版本,而 Web 应用程序则可以.因此,对于 HTML 应用程序,您可以轻松地引入不兼容的更改,因为您在移动 API 破坏 API 至少令人担忧的地方提供了合适的客户端.也许,您会想要保持向后兼容性,这将使您的通用控制器变得丑陋无比.如果没有适当的 api/v1 命名空间,您甚至无法同时拥有两个不同的 API 版本.

The second issue that will arise is the fact that you cannot rely on your mobile users to always have the latest app version where with a webapp you can. So for the HTML app you can easily introduce non-compatible changes because you are delivering a proper client right within where for the mobile API breaking the API is at least concerning. Perhaps, you will want to maintain a backwards compatibility which will make your all purpose controllers ugly as hell. And without a proper api/v1 namespace you even can't have two different API versions at the same time.

您可以通过保持控制器非常精简并将逻辑移到模型中来避免逻辑重复(服务对象也是模型,而不仅仅是 Active Record).

You can avoid duplication of your logic by keeping your controllers very skinny and move the logic out into models (Service Objects are models too, not only Active Records).

3) 您的移动 HTTP 库很可能具有适当的自动 cookie 管理.基于令牌的身份验证再次成为最佳实践.如果它只是 cookie 中的令牌 vs session_id,则不会有太大的胜利.我只能认为它会自动抵御 CSRF 攻击,您可以完全为 API 禁用此保护,因为您的网站用户将不被允许使用 API,只需登录该站点即可(可能是额外的好处).使用基于会话的身份验证,您必须在第一个 API 请求上生成 CSRF 令牌并将其设置在 X-CSRF-Token cookie 中.

3) Your mobile HTTP lib will to a high probability have a proper automatic cookie management. Having token based authentication is just again a best practice. If it is just a token vs session_id within cookie, there will be not much win. I can only think that it will be automatically secure against CSRF attack and you can disable this protection entirely for the API because your website users won't be allowed to consume the API, just by logging in to the site (an additional benefit perhaps). With session based authentication you will have to generate a CSRF token on first API request and set it within X-CSRF-Token cookie.

基于令牌的身份验证的一大优势是它可以扩展到更高的安全性,例如引入过期令牌、HMAC 令牌等,而会话身份验证则不是.请参阅使用会话与令牌进行 API 身份验证

The big advantage of token based authentication is that it is extendable to more security, like introducing expire tokens, HMAC tokens etc, whereby session authentication is not. See Using Sessions vs Tokens for API authentication

我还鼓励您查看 json:api.它来自 ember.js 的创建者,他们在构建 API 时考虑过缩小要做出的决定.另一个有趣的事情是 active_model_serializers gem.Rails:未来五年 作者 Yehuda Katz

I would also encourage you to look at json:api. It comes from the creators of ember.js, who have thought about minifying decisions to take, when building APIs. Another interesting thing is an active_model_serializers gem. An intro to it is given within Rails: The Next Five Years by Yehuda Katz