Web Forms and Ruby on Rails - 15.18 Exposing Web Services on Your Web Site
(Page 3 of 4 )
Problem
You want to offer SOAP and XML-RPC web services from your web application.
Solution
Rails comes with a built-in web service generator that makes it easy to expose a controllers actions as web services. You don't have to spend time writing WSDL files or even really know how SOAP and XML-RPC work.
Here's a simple example. First, follow the directions in Recipe 15.16 to create a database table named items, and to generate a model for that table. Don't generate a controller.
Now, run this from the command line:
./script/generate web_service Item add edit fetch
create app/apis/
exists app/controllers/
exists test/functional/
create app/apis/item_api.rb
create app/controllers/ item_controller.rb
create test/functional/ item_api_test.rb
This creates an item controller that supports three actions: add, edit, and fetch. But instead of web application actions with .rhtml views, these are web service actions that you access with SOAP or XML-RPC.
A Ruby method doesn't care about the data types of the objects it accepts as arguments, or the data type of its return value. But a SOAP or XML-RPC web service method does care. To expose a Ruby method through a SOAP or XML-RPC interface, we need to define type information for its signature. Open up the file app/apis/ item_api.rb and edit it to look like this:
class ItemApi < ActionWebService::API::Base
api_method :add, :expects => [:string, :string], :returns => [:int]
api_method :edit, :expects => [:int, :string, :string], :returns => [:bool]
api_method :fetch, :expects => [:int], :returns => [Item]
end
Now we need to implement the actual web service interface. Open app/controllers/ item_controller.rb and edit it to look like this:
class ItemController < ApplicationController
wsdl_service_name 'Item'
def add(name, value)
Item.create(:name => name, :value => value).id
end
def edit(id, name, value)
Item.find(id).update_attributes(:name => name, :value => value)
end
def fetch(id)
Item.find(id)
end
end
Discussion
The item controller now implements SOAP and XML-RPC web services for the items table. This controller can live alongside an items controller that implements a traditional web interface.*
The URL to the XML-RPC API is http://www.yourserver.com/item/api, and the URL to the SOAP API is http://www.yourserver.com/item/service.wsdl. To test these services, here's a short Ruby script that calls the web service methods through a SOAP client:
require 'soap/wsdlDriver'
wsdl = http://localhost:3000/item/service.wsdl
item_server = SOAP::WSDLDriverFactory.new(wsdl).create_rpc_driver
item_id = item_server.add('foo', 'bar')
if item_server.edit(item_id, 'John', 'Doe')
puts 'Hey, it worked!'
else
puts 'Back to the drawing board...'
end
# Hey, it worked!
item = item_server.fetch(item_id)
item.class # => SOAP::Mapping::Object
item.name # => "John"
item.value # => "Doe"
Here's the XML-RPC equivalent:
require 'xmlrpc/client'
item_server = XMLRPC::Client.new2('http://localhost:3000/item/api')
item_id = item_server.call('Add', 'foo', "bar")
if item_server.call('Edit', item_id, 'John', 'Doe')
puts 'Hey, it worked!'
else
puts 'Back to the drawing board...'
end
# Hey, it worked!
item = item_server.call('Fetch', item_id)
# => {"name"=>"John", "id"=>2, "value"=>"Doe"}
item.class # => Hash
See Also
- Matt Biddulph's article "REST on Rails" describes how to create REST-style web services on top of Rails (http://www.xml.com/pub/a/2005/11/02/rest-on-rails.html)
- Recipe 16.3, "Writing an XML-RPC Client," and Recipe 16.4, "Writing a SOAP Client"
- Recipe 16.5, "Writing a SOAP Server," shows a nonRails implementation of SOAP web services
Next: 15.19 Sending Mail with Rails >>
More Ruby-on-Rails Articles
More By O'Reilly Media
|
This article is excerpted from chapter 15 of the Ruby Cookbook, written by Lucas Carlson and Leonard Richardson (O'Reilly, 2006; ISBN: 0596523696). Check it out today at your favorite bookstore. Buy this book now.
|
|