Class: Jiraby::JSONResource

Inherits:
RestClient::Resource
  • Object
show all
Defined in:
lib/jiraby/json_resource.rb

Overview

A RestClient::Resource that expects JSON data from all requests, and wraps all JSON in native Ruby hashes so you don't have to parse it.

Expectations:

  • All GET, HEAD, DELETE, PUT, POST, and PATCH requests to your REST API will return a JSON string. With JSONResource, the #get, #head, #delete,

    put, #post, and #patch methods return a Hash (if the response is actually

    JSON and can be parsed), or raise a JSONParseError if parsing fails.

  • All payloads (first argument to #put, #post, and #patch) are expected to be JSON strings; you can provide the raw JSON string, or provide a Hash and it will be automatically encoded as a JSON string.

  • All error responses from the REST API are expected to be JSON strings. When an error occurs (such as 401, 404, 500 etc.), normally a RestClient::Exception is raised. With JSONResource, the error response is parsed as JSON and returned as a Hash; no exception is raised.

Constant Summary collapse

@@debug =
false

Instance Method Summary collapse

Constructor Details

#initialize(url, options = {}, backwards_compatibility = nil, &block) ⇒ JSONResource

Returns a new instance of JSONResource.



36
37
38
39
40
# File 'lib/jiraby/json_resource.rb', line 36

def initialize(url, options={}, backwards_compatibility=nil, &block)
  options[:headers] = {} if options[:headers].nil?
  options[:headers].merge!(:content_type => :json, :accept => :json)
  super(url, options, backwards_compatibility, &block)
end

Instance Method Details

#_deleteObject



44
# File 'lib/jiraby/json_resource.rb', line 44

alias_method :_delete, :delete

#_getObject

Aliases to RestClient::Resource methods



43
# File 'lib/jiraby/json_resource.rb', line 43

alias_method :_get, :get

#_headObject



45
# File 'lib/jiraby/json_resource.rb', line 45

alias_method :_head, :head

#_patchObject



48
# File 'lib/jiraby/json_resource.rb', line 48

alias_method :_patch, :patch

#_postObject



46
# File 'lib/jiraby/json_resource.rb', line 46

alias_method :_post, :post

#_putObject



47
# File 'lib/jiraby/json_resource.rb', line 47

alias_method :_put, :put

#delete(additional_headers = {}, &block) ⇒ Object



55
56
57
# File 'lib/jiraby/json_resource.rb', line 55

def delete(additional_headers={}, &block)
  wrap(:_delete, additional_headers, &block)
end

#get(additional_headers = {}, &block) ⇒ Object

Wrapped RestClient::Resource methods that accept and return Hash data



51
52
53
# File 'lib/jiraby/json_resource.rb', line 51

def get(additional_headers={}, &block)
  wrap(:_get, additional_headers, &block)
end

#head(additional_headers = {}, &block) ⇒ Object



59
60
61
# File 'lib/jiraby/json_resource.rb', line 59

def head(additional_headers={}, &block)
  wrap(:_head, additional_headers, &block)
end

#maybe_error_response(&block) ⇒ Object

Yield a response from the given block; if a RestClient::Exception is raised, return the exception's response instead.



124
125
126
127
128
129
130
131
132
# File 'lib/jiraby/json_resource.rb', line 124

def maybe_error_response(&block)
  begin
    yield
  rescue RestClient::RequestTimeout => ex
    raise ex
  rescue RestClient::Exception => ex
    ex.response
  end
end

#parsed_response(response) ⇒ Object

Parse response as JSON and return a Hash or array of Hashes. Raise JSONParseError if parsing fails.



102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/jiraby/json_resource.rb', line 102

def parsed_response(response)
  begin
    json = Yajl::Parser.parse(response)
  rescue Yajl::ParseError => ex
    # FIXME: Sometimes getting "input must be a string or IO" error here
    raise JSONParseError.new(ex.message, response)
  else
    if json.is_a?(Hash)
      return Entity.new(json)
    elsif json.is_a?(Array)
      return json.collect do |hash|
        Entity.new(hash)
      end
    else
      return nil
    end
  end
end

#patch(payload, additional_headers = {}, &block) ⇒ Object



71
72
73
# File 'lib/jiraby/json_resource.rb', line 71

def patch(payload, additional_headers={}, &block)
  wrap_with_payload(:_patch, payload, additional_headers, &block)
end

#post(payload, additional_headers = {}, &block) ⇒ Object



63
64
65
# File 'lib/jiraby/json_resource.rb', line 63

def post(payload, additional_headers={}, &block)
  wrap_with_payload(:_post, payload, additional_headers, &block)
end

#put(payload, additional_headers = {}, &block) ⇒ Object



67
68
69
# File 'lib/jiraby/json_resource.rb', line 67

def put(payload, additional_headers={}, &block)
  wrap_with_payload(:_put, payload, additional_headers, &block)
end

#wrap(method, additional_headers = {}, &block) ⇒ Object

Wrap the given method to return a Hash response parsed from JSON



77
78
79
80
81
82
83
# File 'lib/jiraby/json_resource.rb', line 77

def wrap(method, additional_headers={}, &block)
  puts "#{@url} wrap(#{method})" if @@debug
  response = maybe_error_response do
    send(method, additional_headers, &block)
  end
  return parsed_response(response)
end

#wrap_with_payload(method, payload, additional_headers = {}, &block) ⇒ Object

Wrap the given method to send a Hash payload, and return a Hash response parsed from JSON.



88
89
90
91
92
93
94
95
96
97
# File 'lib/jiraby/json_resource.rb', line 88

def wrap_with_payload(method, payload, additional_headers={}, &block)
  puts "#{@url} wrap_with_payload(#{method}, #{payload})" if @@debug
  if payload.is_a?(Hash)
    payload = Yajl::Encoder.encode(payload)
  end
  response = maybe_error_response do
    send(method, payload, additional_headers, &block)
  end
  return parsed_response(response)
end