34
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

RubyでAPIを叩く(#4 その他ライブラリ編)

Last updated at Posted at 2016-10-15

前回はRuby標準のnet/httpでDigitalOceanのAPIを叩いてみました。

RubyにはHTTPアクセスのためのライブラリがいくつか出ていますが、それらを使うことでよりAPIが叩きやすくなるのかどうか、検証してみたいと思います。

open-uri

net/httpのwrapperとして歴史があるライブラリです。
wget的に、とにかくWebから何か取ってくるには記述量が少なくて済みます。いつものDroplet一覧をやってみます。

do_listdroplet_openuri.rb
require 'open-uri'

token = '(トークン)'
droplet_ep = 'https://api.digitalocean.com/v2/droplets'

res = open(droplet_ep,
  "Authorization" => "bearer #{token}") do |f|
    f.each_line do |line|
      puts line
    end
end

はい、いきなり短いです!
後ろの方なんてレスポンスを行ごとにputsしているだけですので、そこがなければめちゃくちゃ短いですね。

ただし、open-uriには重大な問題がありまして、GETしかできないんですね。一応、POSTができるようにしたりするパッチ等もあるようですが、PUTやPOST、DELETEを多用するAPI操作にはちょっと向かない感じです。

rest-client

次はまさにREST操作のために生まれてきたような名前のrest-clientです。

do_listdroplet_rest-client
require 'rest-client'

token = '(トークン)'
droplet_ep = 'https://api.digitalocean.com/v2/droplets'

res = RestClient.get droplet_ep, { :Authorization => "bearer #{token}" }

puts res

これも短い!GETについてはopen-uriと肩を並べます。

次にDropletを作成する場合、

do_createdroplet_rest-client.rb
require 'rest-client'
require 'json'

token = '(トークン)'
droplet_ep = 'https://api.digitalocean.com/v2/droplets'

data = {
	"name" => "testserver2",
	"region" => "sgp1",
	"size" => "512MB",
	"image" => "ubuntu-14-04-x64",
	"ipv6" => "false"
}.to_json

res = RestClient.post droplet_ep, data, { :Authorization => "bearer #{token}", content_type: :json }

puts res

これもnet/httpに比べればだいぶ短い気がします。
Content-Typeで指定する"application/json"は:jsonとシンボル化されています。

Faraday

FaradayはDigitalOceanの公式SDKも使っているライブラリです。
売りとしては記述の長さ云々よりも"middleware"と呼ばれる拡張の仕組みにより挙動をカスタマイズできることにある、ようです。

do_listdroplet_faraday.rb
require 'uri'
require 'faraday'

droplet_ep = 'https://api.digitalocean.com/v2/droplets'
token = '(トークン)'

uri = URI.parse(droplet_ep)

http = Faraday.new(:url => "#{uri.scheme}://#{uri.host}")
res = http.get do |req|
  req.url uri.path
  req.headers['Authorization'] = "bearer #{token}"
end

p res.body

Faradayは先にアクセス先ホストでオブジェクトを作っておいてから、そのURLのパスに向けてGETなりPOSTなりのメソッドを打ち出すようになっている(同じホストオブジェクトに対して複数のリクエストを出せますね)ため、いったんparseするという面倒なことをしています(最初から分けとけばいいんですが)。

次にPOSTです。

do_createdroplet_faraday.rb
require 'uri'
require 'faraday'
require 'json'

droplet_ep = 'https://api.digitalocean.com/v2/droplets'
token = '(トークン)'

uri = URI.parse(droplet_ep)

http = Faraday.new(:url => "#{uri.scheme}://#{uri.host}")
res = http.post do |req|
  req.url "#{uri.path}"
  req.headers['Authorization'] = "bearer #{token}"
  req.headers['Content-Type'] = "application/json"
  req.body = {
	"name" => "testserver",
	"region" => "sgp1",
	"size" => "512MB",
	"image" => "ubuntu-14-04-x64",
	"ipv6" => "false"
  }.to_json
end

p res.body

rest-clientよりは記述量が多いですが、誤差の範疇な気もします。
で、同じPOSTですが"faraday-middleware"を使ってみると、こうなります。

do_createdroplet_faraday2.rb
require 'uri'
require 'faraday'
require 'faraday_middleware'
require 'json'

droplet_ep = 'https://api.digitalocean.com/v2/droplets'
token = '(トークン)'

uri = URI.parse(droplet_ep)

http = Faraday.new(:url => "#{uri.scheme}://#{uri.host}") do |h|
  h.request :json
  h.adapter Faraday.default_adapter
end

res = http.post do |req|
  req.url "#{uri.path}"
  req.headers['Authorization'] = "bearer #{token}"
  req.body = {
	"name" => "testserver",
	"region" => "sgp1",
	"size" => "512MB",
	"image" => "ubuntu-14-04-x64",
	"ipv6" => "false"
  }
end

p res.body

間違い探しみたいになってますが、ホストオブジェクト作成時にrequest :jsonと指定することで、POSTリクエスト中でのContent-Type記述、およびリクエストボディのjson変換が要らなくなっています。

「それだけかよ」という気もしますが…faraday_middlewareは自分で作り込むことで柔軟に活用するところがミソで、そのままでは大した効果は得られない、ということなのでしょう。

総評

open-uriはしょうがないとして、一般的なREST操作の範疇に要件が収まるならばrest-clientが扱いやすいように思います。API操作に絡めて高度な処理を行うのであれば、Faradayもアリです。

正直なところ、記述量としてはnet/httpから極端に減るものではないので、諸般の事情によりgemがrequireがしにくい開発であれば、無理に使わなくてもなんとかなってしまうでしょう。ただし今回取り上げていないのですが、こういうライブラリは例外処理にも目が行き届いているので、総合的に判断するのが吉なようにも。

私は素人なので、扱いやすいそうなrest-clientでしばらくお世話になってみようかなと思ってます(途中で変えるかもしれませんが)。

34
36
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
36

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?