RSpecApi

When you write a web API, you make a promise to the world.
RSpecApi helps you keep your promise.

The GitHub API example

GitHub provides an extensive API. For instance, you can list the watchers of a repository with:

GET https://api.github.com/repos/:owner/:repo/subscribers

What response should you expect? According to the documentation, one example of possible response is:

Status: 200 OK
Link: <https://api.github.com/resource?page=2>; rel="next",
      <https://api.github.com/resource?page=5>; rel="last"
X-RateLimit-Limit: 5000
X-RateLimit-Remaining: 4999
[
  {
    "login": "octocat",
    "id": 1,
    "avatar_url": "https://github.com/images/error/octocat_happy.gif",
    "gravatar_id": "somehexcode",
    "url": "https://api.github.com/users/octocat"
  }
]

What promises is this example-based documentation making to the API consumers?
If you had to parse the result based solely on one example, you would be filled with doubts like:

The power of RSpecApi to the rescue

RSpecApi provides a new, concise and readable way to document the promises of the endpoint above:

resource :watcher do
  host 'https://api.github.com'
  authorize_with 'YOUR-GITHUB-PERSONAL-API-TOKEN'

  has_attribute :login, type: :string
  has_attribute :id, type: :number
  has_attribute :avatar_url, type: [:null, {string: :url}]
  has_attribute :gravatar_id, type: [:null, :string]
  has_attribute :url, type: {string: :url}

  get '/repos/:owner/:repo/subscribers', collection: true do
    respond_with :ok, owner: existing(:user), repo: existing(:repo)
    respond_with :not_found, owner: unknown(:user), repo: unknown(:repo)
  end
end

This snippet of code is a more comprehensive documentation than an example-based one.
Even though the returned data from the endpoint might differ from call to call, the consumer can always expect:

The best part of RSpecApi is that you can actually verify that GitHub is keeping its API promises at any given time, by executing the snippet of code above through RSpec and ensuring everything is green:

$ rspec spec/features/remote/github/activity/watchers_spec.rb
Watchers
  GET https://api.github.com/repos/:owner/:repo/subscribers
    given an existing owner "rspec-api" and an existing repo "rspec-api"
      responds with a status code that
        should be 200
      responds with headers that
        should include 'Content-Type': 'application/json; charset=utf-8'
      responds with a body that
        should be a JSON Array
        should include the attribute "login" with a string value
        should include the attribute "id" with an integer value
        should include the attribute "avatar_url" with a URL or nil value
        should include the attribute "gravatar_id" with a string or nil value
        should include the attribute "url" with a URL value
    given an unknown owner "i-don-t-exist" and an unknown repo "not-a-repo"
      responds with a status code that
        should be 404

Now, go and run this code for yourself, then tell me what you think. All you need is a GitHub API key (instructions).

Fork RSpecApi on GitHub