前回はcurlコマンドを使って直接APIを叩きました。今回はRubyからAPIを叩いてみます。
RubyでHTTP(S)の通信を操作する方法は色々ありますが、まずは基本ということでnet/http(s)を使います。ぶっちゃけ、APIを叩くならもっと便利なライブラリもいくつかあるのですが…。
Droplet一覧を取得する
まずはいつものをやります。
require 'net/https'
require 'uri'
droplet_ep = 'https://api.digitalocean.com/v2/droplets'
token = '(トークン)'
uri = URI.parse(droplet_ep)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Get.new(uri.request_uri)
req["Authorization"] = "bearer #{token}"
res = http.request(req)
puts res.code, res.msg
puts res.body
GETのときはあまりポイントがない?のですが、APIはたいていSSLなのでnet/httpsをrequireした上で、SSLを使うときのお約束を設定すること、またDigitalOceanに限らずAPIを叩く場合、ヘッダにトークン情報を入れることが多いので、リクエストする際につけておく必要があります。
また上記のコードのままだとres.bodyにjson形式のレスポンスがまるごと入ったままになってしまうので、Ruby上で扱いやすいようにparseしてあげます。
require 'net/https'
require 'uri'
require 'json'
droplet_ep = 'https://api.digitalocean.com/v2/droplets'
token = '(トークン)'
uri = URI.parse(droplet_ep)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Get.new(uri.request_uri)
req["Authorization"] = "bearer #{token}"
res = http.request(req)
puts res.code, res.msg
api_response = JSON.parse(res.body)
api_response['droplets'].each do |item|
puts item['name'], item['disk'], item['memory']
end
APIレスポンスがRubyのhashにパースされるため、その中から任意の情報を取得することができるようになります。
POSTしてみる
前回curlで行ったDroplet作成をnet/httpでやってみます。
require 'net/https'
require 'uri'
require 'json'
droplet_ep = 'https://api.digitalocean.com/v2/droplets'
token = '(トークン)'
uri = URI.parse(droplet_ep)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Post.new(uri.request_uri)
req["Authorization"] = "bearer #{token}"
req["Content-Type"] = "application/json"
data = {
"name" => "testserver",
"region" => "sgp1",
"size" => "512MB",
"image" => "ubuntu-14-04-x64",
"ipv6" => "false"
}.to_json
req.body = data
res = http.request(req)
puts res.code, res.msg, res.body
上半分はさっきとほぼ同じですね。
reqをPOSTとして生成したのと、POSTする内容をhashで作っておいて、jsonに変換しているところがポイントかと思います(まぁ、私も100%受け売りですが)。またPOSTの中身がJSONなので、必ずリクエストヘッダにContent-Typeをセットする必要があります。
curlの場合、しんどいのがPOSTのペイロードでJSONを手書きしなければいけないところなので、ここが多少なりとも記述しやすい形になるのは非常にありがたいところです。
Deleteしてみる
今回も、最後は削除です。
本来はIDを何らかの方法で特定する(ARGVで突っ込むとか)するのがミソだと思うのですが、今回はさっき作ったDropletのIDをハードコードしてしまいます。
require 'net/https'
require 'uri'
droplet_id = '28670468'
droplet_ep = "https://api.digitalocean.com/v2/droplets/#{droplet_id}"
token = '(トークン)'
uri = URI.parse(droplet_ep)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP::Delete.new(uri.request_uri)
req["Authorization"] = "bearer #{token}"
res = http.request(req)
puts res.code, res.msg, res.body
エンドポイントを作るときに、先にIDを埋め込んじゃってます。
発行すると204 no contentが返ってきて、Dropletは削除されました。
もっと楽していいかな
今回はあえてnet/httpを使ってみましたが、冒頭触れたとおりRubyにはもっと便利なライブラリがいっぱいありますし、当のDigitalOcean公式SDKはfaradayというライブラリを使ってたりします。次回以降、それらも掘り下げていきたいなと思います。