LoginSignup
3
3

More than 5 years have passed since last update.

Ruby で WebAPI をコールするサンプルコード

Posted at

概要

  • Ruby で WebAPI をコールするサンプルコードを書いてみた
  • 外部のライブラリを使わず、標準ライブラリのみ使っている (標準ライブラリの使い方を理解できるように)
  • よく使いそうな要素を盛り込んだ (HTTP, HTTPS, GET, POST, JSON, XML, timeout, Basic access authentication, etc.)
  • 動作確認環境: macOS Sierra + Ruby 2.4.0

サンプルのソースコード

require 'json'
require 'net/https'
require 'rexml/document'
require 'uri'

class WebAPIClient

  def initialize()
  end

  def encode(params, encoding)
    return nil if params == nil
    encoded = {}
    params.map{|k,v|
      encoded[k.encode(encoding)] = v.encode(encoding)
    }
    return encoded
  end

  def to_query(params, enc=nil)
    if params != nil && !params.empty?
      return '?' + URI.encode_www_form(params, enc)
    else
      return ''
    end
  end

  def get_response(x)

    # 文字 エンコーディング
    if x['encoding'] != nil
      x['params'] = encode(x['params'], x['encoding'])
    end

    # URL エンコード
    if x['method'] == 'GET'
      url = x['base_url'] + to_query(x['params'])
    elsif x['method'] == 'POST'
      url = x['base_url']
    end

    # URI 文字列をパースして
    # URI::Generic のサブクラスのインスタンスを生成
    uri = URI.parse(url)

    # リクエスト情報を確認用に出力
    puts "URI#to_s: #{uri.to_s}"
    puts "URI#host: #{uri.host}"
    puts "URI#port: #{uri.port}"
    puts "URI#request_uri: #{uri.request_uri}"

    # Net::HTTP オブジェクトを生成
    http = Net::HTTP.new(uri.host, uri.port)

    # 接続時に待つ最大秒数
    http.open_timeout = 5

    # 読みこみ (read(2)) 一回でブロックしてよい最大秒数
    http.read_timeout = 5

    if uri.scheme == 'https'
      # HTTPS の場合に true を設定
      http.use_ssl = true
      # SSL 証明書の検証モード
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end

    # Net::HTTPRequest のサブクラスのインスタンスを生成
    if x['method'] == 'GET'
      req = Net::HTTP::Get.new(uri.request_uri, x['headers'])
    elsif x['method'] == 'POST'
      req = Net::HTTP::Post.new(uri.request_uri, x['headers'])
      req.set_form_data(x['params'])
    end

    # BASIC 認証
    if x['basic_auth'] != nil
      req.basic_auth(x['basic_auth']['account'], x['basic_auth']['password'])
    end

    # TCP コネクションを張り、HTTP セッションを開始
    # ブロックが終わったときに接続を自動的に閉じる
    res = http.start{|h|
      h.request(req)
    }

    # レスポンス情報を確認用に出力
    puts "Net::HTTPResponse#code: #{res.code}"
    puts "Net::HTTPResponse#message: #{res.message}"

    return res
  end

  def parse_json(json)
    return JSON.parse(json)
  end

  def parse_xml(xml)
    return REXML::Document.new(xml)
  end

  def self.invoke(x)

    client = WebAPIClient.new()
    res = client.get_response(x)

    if res.kind_of?(Net::HTTPSuccess)
      if res.content_type.include?('json')
        obj = client.parse_json(res.body)
      elsif res.content_type.include?('xml')
        obj = client.parse_xml(res.body)
      else
        obj = res.body
      end
      # レスポンスを出力
      puts obj
    end
  end

end

# HTTP, POST method, xml response
# ユーザーローカルWikipedia API: http://wikipedia.simpleapi.net/
WebAPIClient.invoke({
  'base_url' => 'http://wikipedia.simpleapi.net/api',
  'method' => 'POST',
  'params' => {
    'keyword' => '紅玉',
    'output' => 'xml'
  },
  'headers' => {
    'User-Agent' => 'Mozilla/5.0 (WebAPIClient; Ruby)'
  }
})

# HTTPS, GET method, JSON response
# Users | GitHub Developer Guide: https://developer.github.com/v3/users/
WebAPIClient.invoke({
  'base_url' => 'https://api.github.com/users/niwasawa',
  'method' => 'GET'
})

参考資料

3
3
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
3
3