我需要一个关于如何在ruby中实现“客户端 - 服务器”Web应用程序的建议。任何指南和最佳实践都非常感谢。我对Ruby方式和所需的宝石感兴趣,因为它是一个理想的平台,以及实现这些东西的一般方式和逻辑。
我不是一个优秀的红宝石程序员或熟练的系统设计师,可悲地多年,所以我真的需要你的帮助,因为我仍然希望这件事最终会闪耀。
应用程序的当前外观应如下所示:
DB + Auth DB< - > API App< - >其他应用:
API应用看起来是制作Sinatra的最佳工具。问题是:
其他应用主要是基于网络的用户界面。这部分的逻辑选择是Rails。主要问题是如何实现客户端身份验证。设计很酷,但它是否可以使用令牌,或者它是更合适的工具?
答案 0 :(得分:5)
好的,这会有点长:
如果您已熟悉Rails,可以查看Rails API gem。该项目致力于从Rails中删除其他基于JSON的RESTful API不需要的内容。
这可能听起来很顺利,但它有它的缺点。首先,您已经阅读了您可能习惯的基本轨道功能所需的所有内容,例如: respond_to
。这可能有点棘手,但是当您发现哪些rails模块最初提供了ActionController::Base
中通常捆绑在Rails中的功能时,这非常简单。
话虽如此,让我举一个例子,说明我上周出于好奇心做的一个小型API项目:
我们有一个主要完成的Rails应用程序。一切正常,但它基本上是单片的。一切都由Rails框架提供。对我们来说幸运的是,所有模型逻辑都捆绑在一个名为core
的宝石中。该应用程序本质上允许登录的客户创建可通过最终用户视图搜索的产品。
目标是为此提供RESTful API,它可以更有效地处理并发和更大的数据文件(即CSV,XLS)。
设计目标让我来到Rails API gem。基本安装在Rails中工作,除了脚本称为rails-api
,即:
rails-api new jsonapi
我在这里的优点是我可以使用其他应用程序中的core
,但没有什么能阻止我将自己的模型引入jsonapi
应用程序。
话虽这么说,你可以做所有标准的Rails好东西,比如路由等。它遵循相同的约定。然后,标准路线最初只对JSON做出反应,有时可能会有点混乱。
让我举一个处理产品的API控制器的例子:
class ProductsController < ApplicationController
include ActionController::HttpAuthentication::Token
before_filter :find_product, :except => [:create, :index]
def index
render :json => @products
end
def create
@product = product.new params[:product]
if @product.save
render :json => @product, :status => :created
else
render :json => @product.errors, :status => :unprocessable_entity
end
end
def show
render :json => @product
end
def update
if @product.update_attributes params[:product]
render :json => @product, :status => :ok
else
render :json => @product.errors
end
end
def destroy
if @product.destroy
render :json => @product, :status => :ok
else
render :json => {:note => I18n.t("messages.deletion_impossible")}, :status => :unprocessable_entity
end
end
protected
def find_product
@product = Product.find params[:id]
end
end
没什么特别的。唯一需要注意的是显式包含ActionController::HttpAuthentication::Token
的第二行。这样可以通过HTTP令牌保护您的aPI。如果您想了解有关保护API的更多信息,我建议Ryan Bates'Guide on Railscasts。
至关重要的是,您在ApplicationController
中提供了一个前置过滤器,如下所示:
class ApplicationController < ActionController::API
include ActionController::HttpAuthentication::Token::ControllerMethods
[...]
before_filter :restrict_access
[...]
def restrict_access
authenticate_or_request_with_http_token do |token, options|
# see if key is valid.
end
end
end
再次注意第二行,您必须手动包含ControllerMethods
,否则控制器不会知道authenticate_or_request_with_http_token
。
您可能知道基于Rails约定扩展API。它的工作方式完全相同,但默认情况下有些东西是故意丢失的。如果您在JSON模板中需要更多灵活性,我建议添加JBuilder(Railscast)。
就个人而言,在客户方面有很多选择。最终我发现它归结为你最喜欢的东西。我个人可以在Rails API之上推荐一个小的node.js层,然后在它前面获得基于backbone.js的单页面应用程序。如果您愿意,也可以尝试AngularJS。您还可以围绕它构建另一个Rails应用程序,并在控制器操作中调用API。
它还取决于您想要定位的平台 - 想到iOS / Android的本机应用程序。
我做的选择是node.js + backbone。它目前对我和项目最有意义。节点层基本上保存与API通信所必需的令牌,并且主干应用程序具有与节点层通信的小型库。但它可能是一把双刃剑,取决于你的API有多复杂。对于一个小例子,这看起来很好,但是可能有很多代码重复只是为了将来自主干应用程序的调用放到Rails API中。
对于身份验证,您可以创建基于客户的API密钥(令牌),然后将控制器逻辑限制为仅接受该密钥允许的数据操作。您可以通过节点层管理会话。编辑:这是授权,而不是身份验证。实际上没有什么能阻止你使用Authlogic和Rails API - 我没有测试它,但它应该可以工作。
我承认我还没有完成这部分 - 我希望其他人可以回答这个架构问题: - )
我希望我能提供一些见解。
P.S。:如果你想测试你的API,我强烈推荐httpie(太棒了!)