Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Client for REST API
Ruby
Branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
spec
.gitignore
.rspec
.travis.yml
Gemfile
LICENSE
README.md
Rakefile
harpy.gemspec

README.md

Harpy

Build Status Code Climate

Client for REST API with HATEOAS

Dependencies

  • Ruby 1.8.7 or 1.9.2
  • gem "typhoeus", "~> 0.2.4"
  • gem "activesupport", ">= 3.1.0"
  • gem "activemodel", ">= 3.1.0"
  • gem "hash-deep-merge", "~> 0.1.1"

Usage

  • Set entry_point url:

    Harpy.entry_point_url = "http://localhost"
    
  • Include Harpy::Resource in your model:

    class MyModel
      include Harpy::Resource
    end
    
    # Mass assignment
    model = MyModel.new "firstname" => "Anthony", "lastname" => "Stark"
    model.attributes = {"company" => "Stark Enterprises"}
    model.firstname # => "Anthony"
    model.company # => "Stark Enterprises"
    
    # Because model is not persisted you can read any attribute, allowing
    # to use form_for on new resources to which the client doesn't know the
    # existing attributes yet
    model.email # => nil
    
    # Fetch by url
    MyModel.from_url "http://localhost/mymodel/1"
    # => instance of MyModel with attributes filled in on 200
    # => nil on 404
    # => raises Harpy::ClientTimeout on timeout
    # => raises Harpy::ClientError on Curl error
    # => raises Harpy::InvalidResponseCode on other response codes
    
    # Fetch multiple by url in parallel
    MyModel.from_url ["http://localhost/mymodel/1", "http://localhost/mymodel/2"]
    
    # Get index
    MyModel.search
    # will call GET http://localhost/mymodel given the following entry_point response:
      {
        "link": [
          {"rel": "my_model", "href": "http://localhost/mymodel"}
        ]
      }
    # => return an array of MyModel instances on 200
    # => raises Harpy::ClientTimeout on timeout
    # => raises Harpy::ClientError on Curl error
    # => raises Harpy::InvalidResponseCode on other response codes
    
    # Search by first_name
    MyModel.search :firstname => "Anthony" # GET http://localhost/mymodel?firstname=Anthony
    
    # Create (POST)
    model = MyModel.new "firstname" => "Anthony"
    model.save # POST http://localhost/mymodel with {"firstname":"Anthony"}
    
    # Get an existing resource by url:
    model = MyModel.from_url "http://localhost/mymodel/1"
    # if the service returns the following response:
      {
        "firstname": "Anthony",
        "lastname": null,
        "urn": "urn:mycompany:mymodel:1"
        "link" => [
          {"rel" => "self", "href" => "http://localhost/mymodel/1"},
          {"rel" => "accounts", "href" => "http://localhost/mymodel/1/accounts"}
        ]
      }
    # we can then do:
    model.firstname # => "Anthony"
    model.link "self" # => "http://localhost/mymodel/1"
    model.link :accounts # => "http://localhost/mymodel/1/accounts"
    
    # Update (PUT) requires resource to have both urn and link to self
    model.attributes = {"firstname" => "Tony"}
    model.save # PUT http://localhost/mymodel/1
    
    # The resource is persisted once it has an urn:
    model.persisted? # => true
    
    # If persisted you can no longer read undefined attributes:
    model.lastname # => nil
    model.email # => will raise NoMethodError
    
  • To find a resource by id you need to define .urn:

    class MyModel
      include Harpy::Resource
      def self.urn(id)
        "urn:mycompany:mymodel:#{id}"
      end
    end
    
    model = MyModel.from_id 1 # will GET http://localhost/urn:mycompany:mymodel:1
    # expecting a permanent redirect (301) to follow or not found (404)
    
  • Rel name to search for in entry_point when getting index can be overridden:

    class MyCustomModel
      include Harpy::Resource
      def self.resource_name
        "custom_model"
      end
    end
    
  • or you can use .with_url(url) for getting index of nested resources:

    class Account
      include Harpy::Resource
      def users
        User.with_url(link "user") do
          User.search
        end
      end
    end
    class User
      include Harpy::Resource
    end
    
  • you can override #url_collection to create nested resources:

    class Account
      include Harpy::Resource
    end
    class User
      include Harpy::Resource
      attr_accessor :account
      def url_collection
        account ? account.link("user") : super
      end
    end
    
  • Fetch multiple resources in parallel:

    class FirstModel
      include Harpy::Resource
    end
    class SecondModel
      include Harpy::Resource
    end
    
    Harpy::Resource.from_url({
       FirstModel => ["http://localhost/firstmodel/1", "http://localhost/firstmodel/2"],
       SecondModel => ["http://localhost/secondmodel/1"],
    })
    # => {FirstModel => [...], SecondModel => [...]}
    

License

harpy is Copyright © 2011 TalentBox SA. It is free software, and may be redistributed under the terms specified in the LICENSE file.

Something went wrong with that request. Please try again.