Class: HttpMagic::Api

Inherits:
BasicObject
Defined in:
lib/http_magic/api.rb

Overview

A magical class that interacts with HTTP resources with a minimal amount of configuration.

Assuming an api where the url www.example.com/api/v1/foo/99 responds with the following.

Header:

Content-Type: application/json

Body:

{
  "name": "Foo Bar"
}

Example

class ExampleApi < HttpMagic::Api
  url 'www.example.com'
  namespace 'api/v1'
  headers({'X-AuthToken' => 'token'})
end

ExampleApi.foo[99].get['name']
=> "Foo Bar"

ExampleApi.foo.create.post(name: 'New Foo')
=> { 'name' => 'New Foo' }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, namespace, headers) ⇒ Api

Returns a new instance of Api.



117
118
119
120
121
# File 'lib/http_magic/api.rb', line 117

def initialize(url, namespace, headers)
  @uri = Uri.new(url)
  @uri.namespace = namespace
  @headers = headers
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(part, *args, &block) ⇒ Object

Instance scoped method_missing that accumulates the URN parts used in forming the URI. It returns a reference to the current instance so that method and [] based parts can be chained together to from the URN. In the case of ExampleApi.foo the ‘foo’ method is accumlated as a URN part that will form the resulting URI.



268
269
270
271
# File 'lib/http_magic/api.rb', line 268

def method_missing(part, *args, &block)
  @uri.parts << part.to_s
  self
end

Class Method Details

.headers(value = :not_provided) ⇒ Object

Sets or returns the request headers for an HttpMagic based class. The headers will be passed along to each resource request being made.

Example

class ExampleApi < HttpMagic:Api
  url 'www.example.com'
  headers({'X-AuthToken' => 'token'})
end


55
56
57
58
59
60
# File 'lib/http_magic/api.rb', line 55

def self.headers(value = :not_provided)
  unless value == :not_provided
    @headers = value
  end
  @headers
end

.method_missing(name, *args, &block) ⇒ Object

Class scoped method_missing that starts the magic of creating urns through meta programming by instantiating an instance of the class and delegating the first part of the urn to that instance. This method is an implementation of the Factory Method design pattern.



113
114
115
# File 'lib/http_magic/api.rb', line 113

def self.method_missing(name, *args, &block)
  new(@url, @namespace, @headers).__send__(name, *args)
end

.namespace(value = :not_provided) ⇒ Object

Sets or returns the namespace for an HttpMagic based class. The namespace will be prefixed to the urn for each request made to the url.

Assuming an api where each resource is namespaced with ‘api/v1’ and where the url www.example.com/api/v1/foo/99 responds with the following.

Header:

Content-Type: application/json

Body:

{
  "name": "Foo Bar"
}

Example

class ExampleApi < HttpMagic:Api
  url 'www.example.com'
  namespace 'api/v1'
end

ExampleApi.foo[99].get['name']
=> "Foo Bar"


88
89
90
91
92
93
# File 'lib/http_magic/api.rb', line 88

def self.namespace(value = :not_provided)
  unless value == :not_provided
    @namespace = value
  end
  @namespace
end

.url(value = :not_provided) ⇒ Object

Sets or returns the uniform resource locator for the HTTP resource.

Example

class ExampleApi < HttpMagic::Api
  url 'www.example.com'
end


102
103
104
105
106
107
# File 'lib/http_magic/api.rb', line 102

def self.url(value = :not_provided)
  unless value == :not_provided
    @url = value
  end
  @url
end

Instance Method Details

#[](part) ⇒ Object

Resource index reference intended to allow for the use of numbers in a urn such as the following ‘foo/99’ being referenced by ExampleApi.foo. It can also be used to allow for HttpMagic methods to be specified for a urn such as ‘foo/get’ being referenced by ExampleApi.foo. Finally, it can be used for urn parts that are not valid Ruby methods such as ‘foo/%5B%5D’ being referenced by ExampleApi.foo.

  • part - a part of a urn such that ‘foo’ and ‘bar’ would be parts of the urn ‘foo/bar’.

Returns a reference to its instance so that urn parts can be chained together.



135
136
137
138
# File 'lib/http_magic/api.rb', line 135

def [](part)
  @uri.parts << part.to_s
  self
end

#deleteObject

Deletes a resource from the URI.

Assuming an api where each resource is namespaced with ‘api/v1’ and where the url www.example.com/api/v1/foo/99 references a specific resource.

Example

class ExampleApi < HttpMagic::Api
  url 'www.example.com'
  namespace 'api/v1'
end

ExampleApi.foo[99].delete
=> ""


155
156
157
158
# File 'lib/http_magic/api.rb', line 155

def delete
  request = Request.new(@uri, headers: @headers)
  request.delete
end

#getObject

Gets a resource from the URI and returns it based on its content type. JSON content will be parsed and returned as equivalent Ruby objects. All other content types will be returned as text.

Assuming an api where each resource is namespaced with ‘api/v1’ and where the url www.example.com/api/v1/foo/99 responds with the following.

Header:

Content-Type: application/json

Body:

{
  "name": "Foo Bar"
}

Example

class ExampleApi < HttpMagic::Api
  url 'www.example.com'
  namespace 'api/v1'
end

ExampleApi.foo[99].get
=> { "name" => "Foo Bar" }


186
187
188
189
190
191
# File 'lib/http_magic/api.rb', line 186

def get
  request = Request.new(@uri,
    headers: @headers
  )
  request.get
end

#post(data = {}) ⇒ Object

POST’s a resource from the URI and returns the result based on its content type. JSON content will be parsed and returned as equivalent Ruby objects. All other content types will be returned as text.

Assuming an api where each resource is namespaced with ‘api/v1’ and where the url www.example.com/api/v1/foo/create responds with the following when a ‘name’ is sent with the request.

Header:

Content-Type: application/json

Body:

{
  "name": "New Foo"
}

Example

class ExampleApi < HttpMagic::Api
  url 'www.example.com'
  namespace 'api/v1'
end

ExampleApi.foo.create.post(name: 'New Foo')
=> { "name" => "New Foo" }


220
221
222
223
224
225
226
# File 'lib/http_magic/api.rb', line 220

def post(data = {})
  request = Request.new(@uri,
    headers: @headers,
    data: data,
  )
  request.post
end

#put(data = {}) ⇒ Object

PUT’s a resource to the URI and returns the result based on its content type. JSON content will be parsed and returned as equivalent Ruby objects. All other content types will be returned as text.

Assuming an api where each resource is namespaced with ‘api/v1’ and where a GET to the url www.example.com/api/v1/foo/99 responds with the following.

Header:

Content-Type: application/json

Body:

{
  "name": "Foo"
}

Example

class ExampleApi < HttpMagic::Api
  url 'www.example.com'
  namespace 'api/v1'
end

ExampleApi.foo[99].put(name: 'Changed Foo')
=> { "name" => "Changed Foo" }


255
256
257
258
259
260
261
# File 'lib/http_magic/api.rb', line 255

def put(data = {})
  request = Request.new(@uri,
    headers: @headers,
    data: data,
  )
  request.put
end