Last active
March 20, 2020 12:17
-
-
Save webuilder240/3b2213456731d74a637b95e48f682570 to your computer and use it in GitHub Desktop.
FaradayっぽいインターフェイスのHTTPクライアント
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require './demo_http.rb' | |
client = DemoHttp::Client.new do |configure| | |
configure.open_timeout = 5 | |
configure.read_timeout = 9 | |
configure.max_attempts = 5 | |
configure.url = "https://httpstat.us" | |
end | |
paths = %w(200 404 500) | |
paths.each do |path| | |
begin | |
response = client.get("/#{path}") do |request| | |
request.params = {body: "hello"} | |
end | |
rescue DemoHttp::HttpClientError => e | |
puts "client error" | |
puts e.response.to_h | |
rescue DemoHttp::HttpServerError => e | |
puts "server error" | |
puts e.response.to_h | |
rescue DemoHttp::ReadTimeout => e | |
puts "timeout" | |
puts e | |
end | |
puts response.to_h | |
end | |
begin | |
error_client = DemoHttp::Client.new do |configure| | |
configure.open_timeout = 5 | |
configure.read_timeout = 9 | |
configure.max_attempts = 5 | |
end | |
rescue DemoHttp::ConfigureError => e | |
puts "set http url" | |
end | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "net/http" | |
require 'json' | |
module DemoHttp | |
class HttpClientError < StandardError | |
attr_accessor :response | |
end | |
class HttpServerError < StandardError | |
attr_accessor :response | |
end | |
class ReadTimeout < StandardError; end | |
class HttpNotFound < HttpClientError; end | |
class HttpTimeoutError < HttpClientError; end | |
class ConfigureError < StandardError; end | |
class Configure | |
attr_accessor :max_attempts, :url, :headers, :open_timeout, :read_timeout | |
def initialize | |
@max_attempts = 5 | |
@headers = {} | |
@content_type = "json" | |
@open_timeout = 5 | |
@read_timeout = 30 | |
end | |
end | |
class Client | |
def initialize | |
yield configure if block_given? | |
end | |
def configure | |
@configure ||= Configure.new | |
end | |
def get (path = nil, &block) | |
invoke(method: __method__, path: path, &block) | |
end | |
def post(path = nil, &block) | |
invoke(method: __method__, path: path, &block) | |
end | |
def put(path = nil, &block) | |
invoke(method: __method__, path: path, &block) | |
end | |
def patch(path = nil, &block) | |
invoke(method: __method__, path: path, &block) | |
end | |
def delete(path = nil, &block) | |
invoke(method: __method__, path: path, &block) | |
end | |
def invoke(method:, path:, &block) | |
raise ConfigureError.new("Please set URL") if configure.url.nil? || configure.url.empty? | |
block.call request if block_given? | |
request.path = path unless path.nil? | |
begin | |
original_response = _invoke(method) | |
rescue Net::ReadTimeout => e | |
raise ReadTimeout | |
end | |
response = Response.new(request, original_response.code, original_response.body, original_response.header) | |
handling_raise_http_error(response) | |
end | |
private | |
def _invoke(method_name) | |
h = http_request(method_name) | |
h.content_type = "application/json" | |
http.use_ssl = target_uri.include?("https://") | |
http.request(h) | |
end | |
def uri | |
@uri = URI.parse(target_uri) | |
end | |
def http | |
@http ||= Net::HTTP.new(uri.hostname, uri.port).tap do |h| | |
h.open_timeout = configure.open_timeout | |
h.read_timeout = configure.read_timeout | |
end | |
end | |
def http_request(method_name) | |
case method_name | |
when :get | |
Net::HTTP::Get.new(uri.request_uri) | |
when :post | |
Net::HTTP::Post.new(uri.request_uri) | |
when :put | |
Net::HTTP::Put.new(uri.request_uri) | |
when :patch | |
Net::HTTP::Patch.new(uri.request_uri) | |
when :delete | |
Net::HTTP::Delete.new(uri.request_uri) | |
end | |
end | |
def request | |
@request ||= Request.new | |
end | |
def handling_raise_http_error(response) | |
case response.status | |
when 200...399 | |
response | |
when 404 | |
e = HttpNotFound.new | |
e.response = response | |
raise e | |
when 400...499 | |
e = HttpClientError.new | |
e.response = response | |
raise e | |
when 500...599 | |
e = HttpServerError.new | |
e.response = response | |
raise e | |
else | |
response | |
end | |
end | |
def target_uri() | |
"#{configure.url}#{request.path}" | |
end | |
end | |
class Request | |
attr_accessor :path, :params, :header | |
def initialize | |
@path = "/" | |
@params = {} | |
@header = {} | |
end | |
end | |
class Response | |
attr_reader :request, :status, :body, :header | |
def initialize(request, status, body, header) | |
@request = request | |
@status = status.to_i | |
@body = body | |
@header = header | |
end | |
def to_h | |
{ | |
request: request, | |
status: status, | |
header: header, | |
} | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment