-
Notifications
You must be signed in to change notification settings - Fork 68
Deprecated v 0.2 Readme (does not work with 0.3.0)
acts_as_api makes creating XML/JSON responses in Rails 3 easy and fun.
The built-in XML/JSON support of Rails is great but:
You surely don’t want to expose your models always with all attributes.
acts_as_api enriches the models and controllers of your app in a rails-like way so you can easily determine how your API responses should look like.
acts_as_api uses the *default Rails serializers* for XML and JSON, so you don’t have to mess around with even more dependencies. Once you change the serializers for your Rails app, they will be changed for acts_as_api too.
As of the version 0.2.0 it supports multiple api rendering templates for a models. This is especially useful for API versioning or for example for private vs. public access points to a user’s profile.
*Note that upgrading to 0.3.0 will break code that worked with previous versions due to a complete overhaul of the lib*
Say you have a model Customer
and every customer has many Orders
.
If you only want to expose the firstname
and lastname
attribute of a customer via the api, you would do something like this:
class Customer < ActiveRecord::Base has_many :orders # let this model act as api! acts_as_api # define the accessible attributes/methods for the api response api_accessible :default => [ :firstname, :lastname ] end
An API template with the name :default
was created, see below how to use it in the controller:
Now you just have to exchange the render
method in your controller for the render_for_api
method.
class CustomersController < ApplicationController def show @customer = Customer.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render_for_api :default, :xml => @customer } format.json { render_for_api :default, :json => @customer } end end end
Try it. The response should now look like this:
<?xml version="1.0" encoding="UTF-8"?> <customer> <firstname>John</firstname> <lastname>Doe</lastname> </customer>
Other attributes of the model like created_at
or updated_at
won’t be included because they were not listed by api_accessible
in the model.
With the different named API templates, API versioning is pretty easy:
class User < ActiveRecord::Base # let this model act as api! acts_as_api # define the accessible attributes/methods for the api response api_accessible :v1_public => [ :firstname, :age ], :v2_public => [ :firstname, :age, :sex ], :v1_private => [ :firstname, :lastname, :age, :sex ], :v2_private => [ :firstname, :lastname, :age, :sex, :phone ] end
Now you could create a method in the application controller of your app:
def api_template(version = :v2, template = :public) "#{version.to_s}_#{template.to_s}".to_sym end
And render the API responses:
class UsersController < ApplicationController # renders the :v2_public template def show @user = User.find(params[:id]) respond_to do |format| format.html # show.html.erb format.xml { render_for_api api_template, :xml => @user } format.json { render_for_api api_template, :json => @user } end end # renders the :v1_private template def profile_deprecated @user = @current_user respond_to do |format| format.html # show.html.erb format.xml { render_for_api api_template(:v1, :private), :xml => @user } format.json { render_for_api api_template(:v1, :private), :json => @user } end end end
You can include metadata elements in the response outside of your objects and collections. Typical usage for this is to include a total results count or page. Just pass in a :meta key with a hash of the meta items you want.
class CustomersController < ApplicationController def index @customers = Customer.paginate(:all, :page = params[:page]) metadata = { :total => @customers.total_entries, :page => params[:page] } respond_to do |format| format.html # show.html.erb format.xml { render_for_api :default, :xml => @customer, :meta => metadata } format.json { render_for_api :default, :json => @customer, :meta => metadata } end end end
You can do basically anything:
-
Include attributes and all other kinds of methods of your model
-
Include child associations (if they also act_as_api this will be considered)
-
Call methods of a parent association
-
Rename attributes, methods, associations
-
Create your own hierarchies
Here are two models from the example app that show how it works.
The model Customer
shows all kinds of ways to add data to your API response.
class Customer < ActiveRecord::Base has_many :orders # let this model act as api! acts_as_api # define the accessible attributes/methods for the api response # some attributes of the model api_accessible :default => [ :firstname, :lastname, :age, # you can include methods :full_name, # include associated model in response :orders, # rename the node for orders { :renamed_orders => :orders }, # put orders in another subnode { :subnode_orders => { :sub_oders => :orders } }, # rename nodes/tag names { :other_node => :say_something }, # create a deeper node hierarchy { :maybe => { :useful => { :for => :say_something } } } ] # some example methods def full_name '' << firstname.to_s << ' ' << lastname.to_s end def say_something "something" end end
The model Order
also acts as api and is even able to access a method of their parent customer.
class Order < ActiveRecord::Base belongs_to :customer # let this model act as api! acts_as_api # define the accessible attributes/methods for the api response # some attributes of the model api_accessible :default => [ :city, :amount, #access a method of the parent association { :parent_name => "customer.full_name" } ] end
If you want a working example right out of the box, grab the example app: github.com/fabrik42/acts_as_api_example
-
Rails 3.0.0
sudo gem install acts_as_api
Then add acts_as_api to the Gemfile of your Rails project
gem 'acts_as_api'
-
Found a bug? github.com/fabrik42/acts_as_api/issues
-
Example App: github.com/fabrik42/acts_as_api_example
(The MIT License)
Copyright © 2010 Christian Bäuerlein
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the ‘Software’), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED ‘AS IS’, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.