Skip to content

Instantly share code, notes, and snippets.

@fespinoza
Last active October 30, 2015 09:18
Show Gist options
  • Save fespinoza/b3e80cb93b6491865bd4 to your computer and use it in GitHub Desktop.
Save fespinoza/b3e80cb93b6491865bd4 to your computer and use it in GitHub Desktop.

Practical Web APIs, rails' style

Me

  • I am about to say many stupid stuff, mostly based on experience

What is an API

Definition

Application programming interface

An API expresses a software component in terms of its operations, inputs, outputs, and underlying types. An API defines functionalities that are independent of their respective implementations, which allows definitions and implementations to vary without compromising the interface

My definition

  • API: an API is a set of Endopints that stablish a contract of the way Clients can comunicate with the system exposing the API
  • Endpoint: a single IN/Out operation
Why we should care?
  • iPhone/Android/JS apps

Properties of Good APIs

  • consistent
  • "self-documented"
  • stable
  • friendly regarding breaking changes

APIs with Rails

When building APIs in a Ruby on Rails world, there are some default choices and convetions to consider

  • HTTP 1.1
  • JSON
  • Rails conventions
  • REST*

* Rails itself is not really restful, it lacks hateoas

Endpoint Structure

In essence, an endpoint is a simple Input / Output operation, then is very easy to test, given endpoints being stateless under REST

Request

  • http verb
  • url
  • headers
  • body/params

Response

  • status code
  • headers
  • body

Basic concerns about endpoint contruction

Authentication

  • HTTP Auth: when i don't need to know who is logging in
  • Token Based Auth: when i want to identify the user and authenticate him

Error Normalziation

{
  "error": {
    "status":  422,
    "id":      "unprocessable_entity",
    "message": "The given params are not valid",
    "documentation_url": "https://api.com/docs",
    "validations": {
      "title": [
        "can't be blank"
      ]
    }
  }
}

the error id can potentially be a custom kind of error id, not necessarily matching the status code, as an "explanation" of this particual error case

Endpoint Design Process

  1. create a proposal
  2. make a PR out of it!
  3. discuss and agree it
  4. mock it
  5. profit

Tips & what not

Useful HTTP headers

  • request headers

    • Content-Type
    • Accept
    • Accept-Language
    • Authorization
    • If-None-Match
    • User-Agent
  • response headers

    • ETag
    • Content-Type

HTTP Status code

  • 2XX - Success
  • 3XX - Redirection
  • 4XX - Client error
  • 5XX - Server error

Design guidelines

https://github.com/interagent/http-api-design https://github.com/hyperoslo/api-playbook

Oops

  • logging
  • error tracking
  • uptime checking
  • event tracking

Rails Gems

Authentication/Authorization

gem 'devise'
gem 'doorkeeper'
gem 'doorkeeper-jwt'
gem 'cancancan'

Versioning

  • Accept header, rather than URL
  • version:
    • routes
    • controllers
    • views
  • a new version of the enpoint, defaults to the previous version
gem 'api-versions'

Other alternatives:

Testing and documentation

gem 'rspec_api_documentation'
gem 'apitome'

Useful Apps

Paw

https://luckymarmot.com

Postman

https://www.getpostman.com

Dash

https://kapeli.com/dash

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment