Creating a Hypermedia Client

Posted on 06 Dec 2012 by Eric Oestrich

Over the past few weeks I wrote a client for a hypermedia api that I created. I think I ended up coming across a pattern that I like in regards to how it's structured.

I have three basic object types: services, loaders, and resources.

The http client used is the gem Farday.

Services

A service is an object that performs an action. For example I have one service that registers users.

class UserRegistrationService < Struct.new(:email, :password)
  def perform
    client.post(user_registration_url, {
      :user => {
        :email => email,
        :password => password
      }
    }
  end
end

Resources

A resource is a data only object. For example I might have a resource for an order.

class Order
  def self.load(json_string)
    new(JSON.parse(json_string))
  end

  def initialize(attrs)
    @email = attrs.fetch("email")
    @links = Links.new(attrs.fetch("_links"))
  end
end

Loaders

A loader is an object that loads up resources for me, going through any of the hypermedia bits that might be necessary. For example I might have a loader that gets a list of orders.

class OrdersLoader < Struct.new(:user)
  def load
    client.basic_auth(user.email, user.password)

    response = client.get("/")
    root = Root.load(response.body)

    response = client.get(root.links.fetch("orders"))
    Orders.load(response.body)
  end
end

In the end I was pretty happy with how this structure ended up and was able to fairly quickly come up with an app that used it.

comments powered by Disqus
Eric Oestrich
I am:
All posts
Creative Commons License
This site's content is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License unless otherwise specified. Code on this site is licensed under the MIT License unless otherwise specified.