API定义也许很简单,但是要做到可扩展性强,调用简单统一,还是要花一些心思。
下面总结一下ruby设置一个灵活api架构的思路和样例:
需求:整合["Google", "Yahoo", "Baidu", "Sogou", 'Bing','Qihu']等的接口调用。
思路:
一:最外层定义一个api.rb类型请求转发模块Test::Api,按照searche_type字段属性的请求类型定向到对应的api请求文件包。(如Test::Api::BaiduApi)
class Searchengine < ActiveRecord::Base include Test::Apiend
module Test module Api def api unless @api se_type = self.searche_type if ["Google", "Yahoo", "Baidu", "Sogou", 'Bing','Qihu'].include?(se_type) klass = "Test::Api::#{self.searche_type}Api::Api".constantize else klass = nil end @api = klass.new(self) end @api end endend
二:在如Test::Api::BaiduApi文件包内定义api.rb来响应对应的请求分发。
module Test module Api module BaiduApi class Api def service(name) unless @services[name] klass = "Test::Api::BaiduApi::#{name}Service".constantize @services[name] = klass.new(self, @search_engine) end return @services[name] end end end end end
三:在如Test::Api::BaiduApi文件包内定义keword_service.rb类来响应具体KeywordService的方法事件请求处理。(同理还可以定义campaign_service.rb等)
module Test module Api module BaiduApi class KeywordService def download_report(campaign_ids, start_date, end_date) path = download_report_base(:Placement1, campaign_ids, start_date, end_date) return import_reports(path) end end end end end
调用示例:
se=Searchengine.find(1)
#其中se.searche_type="Baidu"
srve="keword"
row_count = se.api.service(srvc).download_report(campaign_ids, nil, start_date, end_date)
总结:由于不同api的实际实现逻辑不一样,所以为实现可扩展性,在设计上将各个api的业务逻辑分开管理,但是在调用接口处理上,实现了统一调度。