Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Small Ruby client for discoverable, lazily-loaded, paginated JSON APIs
Ruby
Tag: v0.0.1

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
examples
lib
spec
.gitignore
.rspec
Gemfile
README.mkd
Rakefile
api_bee.gemspec

README.mkd

API BEE

API Bee is a small client / spec for a particular style of JSON API.

These APIs must

  • Expose resource collections as paginated lists, with entries and paging properties.
  • Resource entities in collections must include an 'href' property pointing to the individual resource, so as to provide a degree of discoverability.

A single resource might look like:

{
  'name':        'Foo',
  'description': 'foo resoruce',
  'href':        'http://api.myservice.com/resources/foo'
}

A resource collection looks like:

{
  'href': 'http://api.myservice.com/resources',
  'total_entries': 100,
  'page': 1,
  'per_page': 10,
  'entries': [
    {
      'name':        'Foo',
      'description': 'foo resoruce',
      'href':         'http://api.myservice.com/resources/foo'
    },
    {
      'name':        'Bar',
      'description': 'bar resoruce',
      'href':        'http://api.myservice.com/resources/bar'
    },
    ...
  ]
}

Collection resources must include the fields 'href', 'total_entries', 'page', 'per_page' and 'entries'. This allows clients to paginate and fetch more pages.

Adapters

It is up to individual adapters to talk to different services, handle auth, etc. An adapter must at least implement 'get' for read-only APIs.

class ApiBee::Adapters::Special
  def get(path, options = {})
    # fetch JSON from remote API, passing pagination options if available
  end
end

The use it:

api = ApiBee.setup :special, optional_custom_data

api.get('/my/resources').each do |r|
  r[:name]
end

Lazy loading

ApiBee wraps your adapters in lazy-loading objects. API calls will only be issued when accessing or iterating data.

The 'href' property in entities will be used to load more data. For example:

# /resources
[
  {
    'title': 'Foo bar',
    'href': '/resources/foo-bar'
  }
]

# /resources/foo-bar
{
  'title': 'Foo bar',
  'description': 'Foo description'
}
api = ApiBee.get(:some_adapter)

resources = api.get('/resources') # no API call is made

resource = resources.first # call to /resources is made

resource['title'] # => 'Foo bar', title data available

resource['description'] # => 'Foo description'. Makes internal new request to /resources/foo-bar

Hash adapter

ApiBee ships with an in-memory Hash adapter so it can be use with test/local data (for example a YAML file).

api = ApiBee.setup(:hash, YAML.load_file('./my_data.yml'))

products = api.get('/products') # => ApiBee::Node::List

products.first # => ApiBee::Node::Single

products.each() # iterate current page

products.current_page # => 1

products.paginate(:page => 2, :per_page => 4) # => ApiBee::Node::List # Next page

products.has_next_page? # => false

products.has_prev_page? # => true

products.prev_page # => 1
Something went wrong with that request. Please try again.