You are on page 1of 21

API-based client/server

applications with TDD and


ActiveResource

Wolfram Arnold
www.rubyfocus.biz

In collaboration with:
Kurt Snyder
papercheck.com
marakana.com
Database-backed

Application

ActiveRecord

SQL

DB
API-backed

Client
Application

ActiveResource

JSON

API

Server SQL
Application
DB
Tradeoffs?

DB-backed
Fast
ActiveRecord well developed
Complex relationships possible
Limited scalability—tight coupling
API-backed
Extra network & server latency
Complex relationships more difficult
Scales well to different front-ends—loose coupling
Frontend Scalability

Client Client
Client
Application Application
Application
(Flash or JS) (Mobile)

ActiveResource

JSON

API

Server SQL
Application
DB
Rails ActiveResource

Model objects that behaves ActiveRecord objects


Maps CRUD operations to RESTful API
No Associations
No Validations (added in Rails 3)
Rougher around the edges than ActiveRecord
From CRUD to REST

class Person < ActiveResource::Base


site “http://server.example.com/people”
format :json
end
Person.create(:name => “Joe”)
→ POST /people, {'name':'Joe'}
Person.find(4)
→ GET /people/4
Resourceful Routes

map.resources :people (in config/routes.rb)


people_path, people_url “named route methods”
GET /people → “index” action
POST /people → “create” action
new_person_path, new_person_url
GET /people/new → “new” action
edit_person_path, edit_person_url
GET /people/:id/edit → “edit” action with ID
person_path, person_url
GET /people/:id → “show” action with ID
PUT /people/:id → “update” action with ID
DELETE /people/:id → “destroy” action with ID
Hyperactive Resource

http://github.com/taryneast/hyperactiveresource

Adds Associations
Supports nested routes
/people/5/addresses/3
But: Cannot mix nested and non-nested routes for the
same resource
Adds Validations
Let's do some coding

Demo
RESTful Person Server API with JSON
HyperactiveResource-based client
TDD anyone?

Application

ActiveRecord RSpec model tests


with fixtures, factories
SQL

Test Database
DB
with transaction support
TDD ActiveRecord Style

it “should create the object” do


lambda {
Person.create(:first_name => “Joe”)
}.should change(Person, :count).by(1)
end

it “should destroy the object” do


p = Factory.create(:person)
lambda {
p.destroy
}.should change(Person, :count).by(-1)
end
API-backed

Client
Application

ActiveResource
RSpec model test
JSON

API Test Database


SQL
on
Server
Application Test Server
DB
instance!
Mocks anyone?

FakeWeb gem: http://github.com/chrisk/fakeweb

FakeWeb.register_uri(:get,
"http://server.example.com/people",
:body => "Hello World!")

Body is the mock object.


It should simulate the server response.
Great solution if it's a 3rd party server.
Problems with Mocks?

If the server code is under our control...


What happens if the server API changes but the
mock doesn't?
What process keeps the simulated server
responses and the actual API in sync?
Better ideas?
Beyond Mocks

Remote Specs
Rely on remote server running (in test environment)
Mechanism to set up data
Mechanism to inspect data
Mechanism to clean up data
Distributed Ruby “DRb”
Client
Application
Remote
Method
foo(args) Invocation
DRb Client

DRb

DRb Server

foo(args)

Server
Application
Demo DRb
Gotcha's

ActiveResource::Base.include_root_in_json
after_initialize hook for starting DRb server
:id problem for Objects, via DRb
Need to run server in test mode
Ideas/Questions:
Front Object in DRb?
rake task to start/stop server—reliably find process?
DRb port inflation—better way?
Summary

Server application with REST controller


Client application with ActiveResource
Use DRb to:
test objects
inquire “actual” data
TDD with ActiveResource
BizConf

Aug 4-6, 2010


Amelia Island, FL
Discount code: WOLF
Rails & Web App
Professionals, Entrepreneurs,
for 43% off
Consultants http://bizconf.org?
Small group coupon=WOLF
Network with Who's Who
Organized by Obie
Fernandez of Hashrocket
Highlight: David Allen

You might also like