Springboard Retail Client

Gem Version Build Status Code Climate Coverage Status

This is the Springboard Retail (a point-of-sale/retail management system) client library for Ruby. It provides access to the Springboard Retail HTTP API.

It is a wrapper around the Patron HTTP client library. Supports MRI 1.9+.

You can find documentation here.


You need a recent version of libcurl and a sane build environment.


sudo apt-get install build-essential libcurl4-openssl-dev
gem install springboard-retail


require 'springboard-retail'
springboard = Springboard::Client.new(
  token: 'secret_token'

Resource oriented

resource = springboard[:items][1234]
response = resource.get
response = resource.delete

# Query string generation:
resource1 = springboard[:items]
resource2 = resource.query(:key1 => 'val1', 'key with spaces' => 'val with spaces')
resource2.uri.to_s# => "/items?key%20with%20spaces=val%20with%20spaces&key1=val1"

URI oriented

response = springboard.get '/items/1234'
response = springboard.delete '/items/1234'
item_count = springboard.count '/items'

Collection Resources


Resources include Ruby's Enumerable module for easy iteration over collections:

springboard[:items].each do |item|
  puts item['description']

item_count = springboard[:items].count

usernames = springboard[:users].map {|user| user['login']}


Resources have a filter method that support's Springboard's advanced filter syntax:

active_users = springboard[:users].filter(:active => true)
active_users.each do |user|
  # do something with each active user

# filter returns a new resource which allows for chaining:
items = springboard[:items]
active_items = items.filter(:active => true)
active_items.filter(:price => {'$gt' => 10}).each do |item|
   # ...

# filtering custom fields:
springboard[:items].filter('[email protected]'=> 'XL')


Resources have a sort method that accepts any number of sort options. Note that each call to sort overwrites any previous sorts.

resource.sort(:id, :price)

# returns a new resource for chaining:
resource.sort(:description, :created_at).filter(:active => true).each do |item|
  # ...

Returning select fields

Resources have a only method that accepts any number of field keys to return only the selected fields. Note that each call to only overwrites any previous fields.

resource.only(:public_id, :updated_at)

# returns a new resource for chaining:
resource.only(:public_id, :updated_at).filter(:active => true).each do |item|
  # ...

Creating Resources

Create a new resource via POST:

collection = client[:items]
response = collection.post! :description => 'Some New Item'
response.status_line# => "HTTP/1.1 201 Created"

# To fetch the newly created resource:
new_item_response = response.resource.get!
new_item_response[:description]# => "Some New Item"

Embedding Related Resources

Use the embed method to include the contents of related resource in the response body of each item in the collection:

collection = client[:sales][:orders].embed(:customer, :location)
# => {
  "id" => 1,
  "customer_id" => 2,
  "customer" =>  {
    # customer data
  "location_id" => 3,
  "location" =>  {
    # location data

The embed method accepts one or more arguments as symbols or strings. It supports chaining and will merge the results of multiple calls.

Looping while results exist

Issuing deletes while iterating over a collection resource can cause the pagination to shift resulting in unexpected behavior. Use while_results when you want to:

  • Consume messages from a queue, deleting each message after it has been processed.
  • Delete all resources in a collection that doesn't support a top-level DELETE method.

For example:

collection = client[:system][:messages]
collection.while_results do |message|
  # process message here...

Request body

If the request body is a Hash, it will automatically be serialized as JSON. Otherwise, it is passed through untouched:

# this:
springboard[:some_collection].post :a => 1, :b => 2

# is equivalent to this:
springboard[:some_collection].post '{"a":1,"b":2}'


response = springboard[:items][1].get

response.status # Response status code as an Integer
response.success? # true/false depending on whether 'status' indicates non-error
response.body # Returns a Springboard::Client::Body object (see below)
response.raw_body # Returns the raw response body as a string
response[:some_key] # Returns the corresponding key from 'body'
response.headers # Response headers as a Hash
response.resource # Returns a Resource if the response included a "Location" header, else nil

Response Body

Given the following JSON response from the server:

  "id": 1234,
  "custom": {
    "color": "Blue"

Here are the various ways you can access the data:

body = response.body

# Symbols and strings can be used interchangeably for keys
body[:id]# => 1234

body[:custom][:color]# => "Blue"

body['custom']['color']# => "Blue"

body.to_hash# => {"id"=>1234, "custom"=>{"color"=>"Blue"}}

response.raw_body# => "{\"id\":1234,\"custom\":{\"color\":\"Blue\"}}"

Bang variants

All HTTP request methods have a bang variant that raises an exception on failure:

response = springboard[:i_dont_exist].get
response.status# => 404

springboard[:i_dont_exist].get!# Raises Springboard::Client::RequestFailed exception

# To access the response from the exception:
rescue Springboard::Client::RequestFailed => error
  puts error.response.status
end# => 404


# Log request/response trace to stdout
client.debug = true

# Or, log to a file
client.debug = '/path/to/file.log'

# Same values can be passed via :debug option to client constructor
client = Springboard::Client.new '<url>', :debug => true