You want to offer SOAP and XML-RPC web services from your web application.
Rails comes with a built-in web service generator that makes it easy to expose a controllers actions as web services. You don have to spend time writing WSDL files or even really know how SOAP and XML-RPC work.
Heres 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 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 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
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.[8]
[8] You can even add your web interface actions to the ItemController class. Then a single controller will implement both the traditional web interface and the web service interface. But you can define a web application action with the same name as a web service action, because a controller class can contain only one method with a given name.
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, heres 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, ar) 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"
Heres 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
Strings
Numbers
Date and Time
Arrays
Hashes
Files and Directories
Code Blocks and Iteration
Objects and Classes8
Modules and Namespaces
Reflection and Metaprogramming
XML and HTML
Graphics and Other File Formats
Databases and Persistence
Internet Services
Web Development Ruby on Rails
Web Services and Distributed Programming
Testing, Debugging, Optimizing, and Documenting
Packaging and Distributing Software
Automating Tasks with Rake
Multitasking and Multithreading
User Interface
Extending Ruby with Other Languages
System Administration