A Sinatra JSON API Demo

What Is It?

This is a small project to demonstrate how to implement a basic JSON API in Ruby via a small Sinatra application made of one file with less than 100 lines of code.

Who's It For?

It's for anyone who wants to play with Sinatra from a starting point that does something small, functional, and understandable.

I made it to test iOS applications that have to talk to a JSON API. But really, anyone who wants to play with serving or consuming a JSON API or HTTP programming is more than welcome to fork and use it.

What Does It Do?

It was built to facilitate the testing of a client that needed to be able to request to /login successfully with a single user account and get a token back for future request authentication along with some account information in JSON.

As a resource for the actual business-value requests, I picked /contacts, which will return an arbitrary number of pseudo-randomly generated contacts as JSON. Finally, the user account can expire that token by passing it to a /logout request.

In other words, multiple clients can hit it with the same credentials and get back the same session authentication token to use for additional requests to get a list of contacts. But if one logs out, the token expires for the other clients. Then everyone has to log back in to get the new current valid token.

Quick Start

To run the application simply do the following:

Clone the repo and navigate to its directory.

$ git clone

$ cd sinatra-api-demo/

If necessary, install the gems*. Start the Sinatra API server.

$ ruby sinatra_api_demo.rb

If you'd like to play with the app and to see changes on every request you can load the application with Shotgun instead.

$ shotgun sinatra_api_demo.rb

If you'd like to bind the port to 4567 and set the server to listen on all interfaces with Shotgun run the following:

$ shotgun sinatra_api_demo.rb -o -p 4567

That's it**!

If you like, you can just run the request runner script from the terminal in the same directory to see the API in action.

$ ruby request_runner.rb

API Documentation

When running, the API server is available on http://localhost:4567 (or port :9393 if you're running it with Shotgun without setting the port to 4567) and has the following routes:

POST to /login with the parameters user=user, password=password; e.g.:

$ curl -v localhost:4567/login -d 'user=user' -d 'password=password'

This returns the following response:

{ "token": "sOmeT0ken", "accountNumber": "0123456789", "accountName": "ACME COMPANY" }

GET to /contacts with token passed in the token header; e.g.:

$ curl -v localhost:4567/contacts -H 'token:sOmeT0ken'

This returns a response like this, or perhaps one much longer:

{ "contactList": [ { "firstName": "Dawson", "lastName": "O'Brien", "phone": "226-447-5207", "email": "dawson.o'" }, { "firstName": "Kyle", "lastName": "Lawson", "phone": "733-514-3858", "email": "" } ] }

GET to /logout with token passed in the token header; e.g.:

$ curl -v localhost:4567/logout -H 'token:sOmeT0ken'

This returns a 200 OK response.

All other requests to the API are caught by the not_found Sinatra helper and return as a 4xx error.

For example:

GET to / with token passed in the token header; e.g.:

$ curl -v localhost:4567/logout -H 'token:sOmeT0ken'

This returns a 400 Bad Request response.


If you're comfortable with Ruby and gems, feel free to skip right to playing with the sinatra_api_demo.rb script. The server will run anywhere Sinatra and JSON are installed and the script has permission to CRUD a text file.

You can use cURL, telnet, or your favorite HTTP client to hit the API with the server running.

Alternately, just run the request_runner.rb script from the same directory to get the output of running requests against the API routes.

It can be called with the following options from the command line:

$ ruby request_runner.rb --help

Usage: request_runner [options]

-v, --verbose Enable verbose mode.

-s, --step Step through the requests with user prompting.

-h, --help Display this help message.

Make sure the Curb gem is installed. If you're also installing and using the Shotgun gem, switch the comments on lines 12 and 14.

I've also included the example curl commands above each of the request methods that the API will respond to in the source of the sinatra_api_demo.rb script. Just make sure to use the current token, which will also be available in the token.tmp file generated by the script after the first validation attempt.


*If you don't have them and want to install the gems, I recommend either EITHER running:

$ gem install sinatra

$ gem install json

$ gem install curb

$ gem install shotgun

$ gem install slop

$ gem install pry

OR by using Bundler to use the included Gemfile (see #3, below):

$ gem install bundler

$ bundle install

Project Extras:

** The following files were added to make getting up and running even easier by making sure you have Ruby 2.1.1 with the Sinatra and JSON gems:

  1. .ruby-version: works with RVM and rbenv to automatically specify a Ruby version; the project was written on Ruby 1.9.3. and has been tested on Ruby 2.1.1
  2. ruby-gemset: works with RVM to create and use a gemset for the project.
  3. Gemfile: use with Bundler to ensure the gems required by sinatra_api_demo.rb and request_runner.rb are installed