Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Make Hypermedia APIs in Ruby

Make Hypermedia APIs in Ruby

This presentation is an introduction of Hypermedia and how to make Hypermedia APIs in Ruby with tools like ActiveModel::Serializers or ROAR.

Nicolas Mérouze

May 07, 2013
Tweet

More Decks by Nicolas Mérouze

Other Decks in Programming

Transcript

  1. URIs (e.g. /posts, /posts/42) Media types (e.g. application/json, text/html) Request

    and response codes (e.g. 200, 302, 404) Requests methods (e.g. GET, POST, PATCH, DELETE)
  2. Identification of resources Manipulation of resources through these representations Self-descriptive

    messages Hypermedia as the engine of application state (aka HATEOAS)
  3. HATEOAS “A client does not assume that any particular action

    is available for any particular resources beyond those described in representations previously received from the server.” – Wikipedia
  4. class AdminUserSerializer < ActiveModel::Serializer attributes :id, :email end class PostSerializer

    < ActiveModel::Serializer attributes :id, :title has_one :admin_user end
  5. { "posts": [ { "admin_user": { "email": "[email protected]", "id": 1

    }, "id": 1, "title": "Welcome to Hyper" } ] }
  6. { "admin_users": [ { "email": "[email protected]", "id": 1 } ],

    "posts": [ { "admin_user_id": 1, "id": 1, "title": "Welcome to Hyper" } ] }
  7. class PostsController < ApplicationController include Roar::Rails::ControllerAdditions respond_to :json def index

    posts = Post.all respond_with posts, :represent_items_with => PostRepresenter end end
  8. { "posts": [ { "id": 1, "links": [ { "href":

    "http://hyper.com/posts/1", "rel": "self" } ], "title": "Welcome to Hyper" } ] }
  9. { "posts": [ { "_links": { "self": { "href": "http://hyper.com/posts/1"

    } }, "id": 1, "title": "Welcome to Hyper" } ] }
  10. Blog.collection :posts do |c| c.href '/posts' c.methods get: :self, post:

    :create c.resource do |r| r.href '/posts/{id}' r.methods get: :self, patch: :update, delete: :destroy r.integer :id r.string :title end c.action :self do |a| a.integer :limit a.array :title_in end c.action :create do |a| a.string :title, required: true end end
  11. GET /posts { "posts": [{ "id": 42, "title": "Hyper Welcome!"

    }, { "id": 43, "title": "Hyper Goodbye!" }], "meta": { "actions": [ { "rel": "self", "method": "get", "href": "/posts", "params": [{"name": "limit", "type": "integer"}] }, { "rel": "create", "method": "post", "href": "/posts", "params": [{"name": "title", "type": "string", "required": true}] } ] } }
  12. GET /posts/42 { "posts": [{ "id": 42, "title": "Hyper Welcome!"

    }], "meta": { "actions": [ { "rel": "self", "method": "get", "href": "/posts/42" }, { "rel": "update", "method": "patch", "href": "/posts/42" }, { "rel": "destroy", "method": "delete", "href": "/posts/42" } ] } }
  13. Nicolas Mérouze Contact me if you need to make a

    good API @nmerouze http://speakerdeck.com/nmerouze http://merouze.me