2015-05-11

Ruby / Sinatra / Rails : Grape & Swagger

這邊盡量簡單的寫這篇,首先Ruby的swagger使用grape這個gem實作,所以看完Grape就完成一大半了,而有gem 的 3 + 1套件(就一個眾星拱月的概念...),分別為


gem 'grape'
gem 'grape-swagger'
gem 'grape-swagger-rails'
gem 'rack-contrib'

rack-contrib直接略過,上rack就用一下唄,有寫swagger的一點都不重要,最多幫忙打view / UI / 顯示doc而已,也直接略過,所以只剩下最重要的grape

grape是建構在rack上,而Ruby / Sinatra / Rails都可以使用,還可以上ActiveRecord,裡面有完整的route / helper / filter...機制,所以README寫得超複雜,不過以下簡單講,畢竟能做測試才能走第一步

Rails要這樣安裝,類似在config/application.rb內加上


config.paths.add File.join('app', 'api'), glob: File.join('**', '*.rb')
config.autoload_paths += Dir[Rails.root.join('app', 'api', '*')]

這樣你的專案啟動時就會自動載入app/api/*.rb,而Kawaii就是我的API,它寫在app/api/kawaii.rb內,再來是route.rb


mount Kawaii::API => '/'

它會先跑Rails的middleware,去找有沒有該path才會到Rails端,這邊注意的是通常API的path都要在最上面才是

再來是主體部分,先顯示我的code,然後來做導讀

require 'grape'
require 'grape-swagger'
module Kawaii
  class APIv1 < Grape::API
    version :v1 , using: :path
    helpers do
      def current_user
        123
      end
    end
    desc 'Update a spline.'
    params do
      requires :id, type: Integer, desc: 'Spline id.'
      optional :reticulated, type: Boolean, default: true, desc: 'True if the spline is reticulated.'
    end
    get ':id' do
      { splines_url: params[:id] }
    end
  end
  class APIv2 < Grape::API
    version :v2 , using: :path
    helpers do
      def current_user
        234
      end
    end
    desc 'Update a spline.'
    params do
      requires :id, type: Integer, desc: 'Spline id.'
      optional :reticulated, type: Boolean, default: true, desc: 'True if the spline is reticulated.'
    end
    get ':id' do
      { splines_url: current_user }
    end
  end
  class API < Grape::API
    format :json
    prefix :api
    add_swagger_documentation
    mount Kawaii::APIv1
    mount Kawaii::APIv2
  end
end

從最後開始看,外面包一層Kawaii略過,API繼承Grape::API略過

format = redner :format,也就是這整票API都會用json的方式傳出,官方支援一票奇怪的格式可以玩,還包括邪惡的jsonp超讚的

prefix 全等於root path,所以這樣寫會變成"/api/..."開頭的網址

add_swagger_documentation ......還沒研究後補

mount Kawaii::APIvN 這邊來拆版本的API,建議一開始就保留讓自己有後路X"D

=======再來是 Kawaii::APIvN

version :v1 , using: :path 等於此行以下的code都是v1,很像ruby的private的用法,而using是辨認版本使用path,所以此行以下的網址加上述會是"/api/v1/...",而還有一票東西可以用,類似放在header內有的沒的

helpers do ... end 這邊當作 global method 來看就好,和application_controller / application_helper的method的作用一樣,單純拿來共用的,且注意,version :v1之下的就只屬於v1的methods能用,和v2有相同名稱的和此無關且不會覆寫


[desc , params , get]這些是一整套,可以缺但不能分開看,請記得

desc 其實就是 doc

params do ... end 所有有需要傳入的 params
    requires 必要值
    optional 非必要值
    //其實還有group,可能是任一或多數重複,還沒玩過不知道它是啥,請訪客提示X"D
        type , default ... 這類就是過濾之類的,而且還能上regex,格式錯誤會直接吐錯誤訊息回去{error:'xxx error'}超帥氣的

get,這是最後的,其實就是當controller來使用,而最後吐回的值直接用hash不用xxx.to_json,因為會自動幫你做掉,而類似 '/yoo/:id/hoo/:kind' 的path的寫法,這就是傳統的params的寫法了,配上面的params使用,不然就要用get / post的方式傳入了(網址後綴或是post body)

上面網址弄好後你就有這樣的網址可以玩"/api/v2/123"

okay,而rack系列的另外一個特點,不會有log,因為log都要另外做,不會有route所以rails route打到死連個屁都噴不出來,有以上基本之後再來看這份超級長的README教學,應該就看得懂了才是 & 建議看一次,真的啥鬼都支援,活性超高的,以後都拿這個鬼來打API X"D

https://github.com/intridea/grape

而先不要管grape-swagger / grape-swagger-rails了,先把API打對唄,而上面裝可愛的v1 & v2的code其實可以不用另外mount,可以全部打在一起(複製貼上就好),且全部不會亂掉呦,用類似private定義method的方式來想一切就都順暢了(該行以下全都是private methods) 介紹到此,以上

沒有留言:

張貼留言