1
0
Fork 0
mirror of https://github.com/rails/rails.git synced 2022-11-09 12:12:34 -05:00
rails--rails/activeresource
Pratik Naik dc4eec1129 Merge docrails:
commit e6afd8b273
Author: Xavier Noria <fxn@hashref.com>
Date:   Thu May 8 23:49:36 2008 +0200

    Overall documentation improvement and markup corrections. Zillion changes.

commit 2fead68b31
Author: Austin Putman <austin@emmanuel.local>
Date:   Wed May 7 19:35:46 2008 -0700

    Documented class methods on ActionController::Routing.  These are dangerous, and mostly used for testing.

commit f5b84182db
Author: Teflon Ted <github@rudiment.net>
Date:   Wed May 7 16:08:49 2008 -0400

    Added explanation about errant inflections not being patched in the future in order to avoid breaking legacy applications.

commit 370f4f5172
Author: Sunny Ripert <negatif@gmail.com>
Date:   Wed May 7 14:00:59 2008 +0200

    Applied list conventions in AR::Base

commit 5bd18429f0
Author: Sunny Ripert <negatif@gmail.com>
Date:   Wed May 7 13:53:35 2008 +0200

    Renamed Options list to Attributes list whenever they weren't option hashes in AR::Base

commit d912bd5672
Author: Yaroslav Markin <yaroslav@markin.net>
Date:   Wed May 7 13:50:28 2008 +0400

    Add a filter_parameter_logging usage hint to generated ApplicationController.
    This may help to remind the developer to filter sensitive information from application logs.
    Closes #11578

commit b243de0db3
Author: Jack Danger Canty <git@6brand.com>
Date:   Tue May 6 23:39:47 2008 -0700

    doc: disambiguating an example ActiveRecord class

commit f81d771f06
Author: Jack Danger Canty <git@6brand.com>
Date:   Tue May 6 23:35:05 2008 -0700

    doc: ActiveRecord::Reflection::AssociationReflection#through_reflection

    Added documentation demonstrating the use of #through_reflection for
    finding intervening reflection objects for HasManyThrough
    and HasOneThrough.

commit ae6b46f00b
Author: Cheah Chu Yeow <chuyeow@gmail.com>
Date:   Wed May 7 13:47:41 2008 +0800

    Document AttributeAssignmentError and MultiparameterAssignmentErrors.

commit 8f463550b5
Author: John Barnette <jbarnette@gmail.com>
Date:   Tue May 6 22:46:44 2008 -0700

    Killing/fixing a bunch of outdated language in the AR README.

commit aca44bcd92
Author: Cheah Chu Yeow <chuyeow@gmail.com>
Date:   Wed May 7 13:34:52 2008 +0800

    Make a note about ActiveResource::Timeouterror being raised when ARes calls timeout.

commit 284a930a93
Author: Jonathan Dance <jd@wuputah.com>
Date:   Tue May 6 14:58:26 2008 -0400

    improvements to the page caching docs

commit 9482da6213
Author: Sunny Ripert <negatif@gmail.com>
Date:   Mon May 5 18:13:40 2008 +0200

    validates_numericality_of() "integer" option really is "only_integer"

commit e9afd6790a
Author: Sunny Ripert <negatif@gmail.com>
Date:   Mon May 5 12:11:59 2008 +0200

    Harmonized hash notation in AR::Base

commit 67ebf14a91
Author: Sunny Ripert <negatif@gmail.com>
Date:   Mon May 5 12:06:19 2008 +0200

    Turned options into rdoc-lists in AR::Base

commit 0ec7c0a41d
Author: Marshall Huss <mwhuss@Macbook.local>
Date:   Sun May 4 23:21:33 2008 -0400

    Added information of how to set element_name in the case the user has a name confliction with an existing model

Signed-off-by: Pratik Naik <pratiknaik@gmail.com>
2008-05-09 10:40:50 +01:00
..
lib Merge docrails: 2008-05-09 10:40:50 +01:00
test Rescue from Timeout::Error in ActiveResource::Connection. 2008-04-22 09:30:56 +12:00
CHANGELOG Fixed response logging to use length instead of the entire thing (seangeo) [#27 state:resolved] 2008-04-29 17:16:36 -05:00
MIT-LICENSE Version updates and missing licenses 2006-09-15 10:13:27 +00:00
Rakefile sshpublisher needs to be explicitly required now, apparently 2008-03-18 04:46:51 +00:00
README Update XML documentation examples to include explicit type attributes. Closes #9754 [hasmanyjosh] 2007-11-06 18:33:45 +00:00

= Active Resource

Active Resource (ARes) connects business objects and Representational State Transfer (REST)
web services.  It implements object-relational mapping for REST webservices to provide transparent 
proxying capabilities between a client (ActiveResource) and a RESTful service (which is provided by Simply RESTful routing
in ActionController::Resources).

== Philosophy

Active Resource attempts to provide a coherent wrapper object-relational mapping for REST
web services. It follows the same philosophy as Active Record, in that one of its prime aims
is to reduce the amount of code needed to map to these resources.  This is made possible 
by relying on a number of code- and protocol-based conventions that make it easy for Active Resource
to infer complex relations and structures.  These conventions are outlined in detail in the documentation
for ActiveResource::Base.

== Overview

Model classes are mapped to remote REST resources by Active Resource much the same way Active Record maps model classes to database
tables.  When a request is made to a remote resource, a REST XML request is generated, transmitted, and the result
received and serialized into a usable Ruby object.

=== Configuration and Usage

Putting ActiveResource to use is very similar to ActiveRecord.  It's as simple as creating a model class
that inherits from ActiveResource::Base and providing a <tt>site</tt> class variable to it:

   class Person < ActiveResource::Base
     self.site = "http://api.people.com:3000/"
   end

Now the Person class is REST enabled and can invoke REST services very similarly to how ActiveRecord invokes
lifecycle methods that operate against a persistent store.

   # Find a person with id = 1
   ryan = Person.find(1)
   Person.exists?(1)  #=> true

As you can see, the methods are quite similar to Active Record's methods for dealing with database
records.  But rather than dealing with 

==== Protocol

Active Resource is built on a standard XML format for requesting and submitting resources over HTTP.  It mirrors the RESTful routing 
built into ActionController but will also work with any other REST service that properly implements the protocol. 
REST uses HTTP, but unlike "typical" web applications, it makes use of all the verbs available in the HTTP specification:

* GET requests are used for finding and retrieving resources.
* POST requests are used to create new resources.
* PUT requests are used to update existing resources.
* DELETE requests are used to delete resources. 

For more information on how this protocol works with Active Resource, see the ActiveResource::Base documentation;
for more general information on REST web services, see the article here[http://en.wikipedia.org/wiki/Representational_State_Transfer].

==== Find

GET Http requests expect the XML form of whatever resource/resources is/are being requested.  So,
for a request for a single element - the XML of that item is expected in response:

   # Expects a response of
   #
   # <person><id type="integer">1</id><attribute1>value1</attribute1><attribute2>..</attribute2></person>
   #
   # for GET http://api.people.com:3000/people/1.xml
   #
   ryan = Person.find(1)

The XML document that is received is used to build a new object of type Person, with each
XML element becoming an attribute on the object.

   ryan.is_a? Person  #=> true
   ryan.attribute1  #=> 'value1'

Any complex element (one that contains other elements) becomes its own object:

   # With this response:
   #
   # <person><id>1</id><attribute1>value1</attribute1><complex><attribute2>value2</attribute2></complex></person>
   #
   # for GET http://api.people.com:3000/people/1.xml
   #
   ryan = Person.find(1)
   ryan.complex  #=> <Person::Complex::xxxxx>
   ryan.complex.attribute2  #=> 'value2'

Collections can also be requested in a similar fashion

   # Expects a response of
   #
   # <people type="array">
   #  <person><id type="integer">1</id><first>Ryan</first></person>
   #  <person><id type="integer">2</id><first>Jim</first></person>
   # </people>
   #
   # for GET http://api.people.com:3000/people.xml
   #
   people = Person.find(:all)
   people.first  #=> <Person::xxx 'first' => 'Ryan' ...>
   people.last  #=> <Person::xxx 'first' => 'Jim' ...>

==== Create

Creating a new resource submits the xml form of the resource as the body of the request and expects
a 'Location' header in the response with the RESTful URL location of the newly created resource.  The
id of the newly created resource is parsed out of the Location response header and automatically set
as the id of the ARes object.

  # <person><first>Ryan</first></person>
  #
  # is submitted as the body on
  #
  # POST http://api.people.com:3000/people.xml
  # 
  # when save is called on a new Person object.  An empty response is
  # is expected with a 'Location' header value:
  #
  # Response (201): Location: http://api.people.com:3000/people/2
  #
  ryan = Person.new(:first => 'Ryan')
  ryan.new?  #=> true
  ryan.save  #=> true
  ryan.new?  #=> false
  ryan.id    #=> 2

==== Update

'save' is also used to update an existing resource - and follows the same protocol as creating a resource
with the exception that no response headers are needed - just an empty response when the update on the
server side was successful.

  # <person><first>Ryan</first></person>
  #
  # is submitted as the body on
  #
  # PUT http://api.people.com:3000/people/1.xml
  #
  # when save is called on an existing Person object.  An empty response is
  # is expected with code (204)
  #
  ryan = Person.find(1)
  ryan.first #=> 'Ryan'
  ryan.first = 'Rizzle'
  ryan.save  #=> true

==== Delete

Destruction of a resource can be invoked as a class and instance method of the resource.

  # A request is made to
  #
  # DELETE http://api.people.com:3000/people/1.xml
  #
  # for both of these forms.  An empty response with
  # is expected with response code (200)
  #
  ryan = Person.find(1)
  ryan.destroy  #=> true
  ryan.exists?  #=> false
  Person.delete(2)  #=> true
  Person.exists?(2) #=> false


You can find more usage information in the ActiveResource::Base documentation.