Home arrow Ruby-on-Rails arrow Page 3 - Web Forms and Ruby on Rails
RUBY-ON-RAILS

Web Forms and Ruby on Rails


In this fifth article of a six-part series covering web development and Ruby on Rails, you'll learn how to create an AJAX form and more. This article is excerpted from chapter 15 of the Ruby Cookbook, written by Lucas Carlson and Leonard Richardson (O'Reilly, 2006; ISBN: 0596523696). Copyright 2006 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

Author Info:
By: O'Reilly Media
Rating: 4 stars4 stars4 stars4 stars4 stars / 33
April 19, 2007
TABLE OF CONTENTS:
  1. · Web Forms and Ruby on Rails
  2. · 15.17 Creating an Ajax Form
  3. · 15.18 Exposing Web Services on Your Web Site
  4. · 15.19 Sending Mail with Rails

print this article
SEARCH DEVARTICLES

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

  1. 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)
  2. Recipe 16.3, "Writing an XML-RPC Client," and Recipe 16.4, "Writing a SOAP Client"
  3. Recipe 16.5, "Writing a SOAP Server," shows a nonRails implementation of SOAP web services


blog comments powered by Disqus
RUBY-ON-RAILS ARTICLES

- Ruby-on-Rails Faces Second Security Flaw in ...
- Ruby 2.0 Prepped for February 2013 Release
- Why LinkedIn Switched from Ruby on Rails
- Adding Style with Action Pack
- Handling HTML in Templates with Action Pack
- Filters, Controllers and Helpers in Action P...
- Action Pack and Controller Filters
- Action Pack Categories and Events
- Logging Out, Events and Templates with Actio...
- Action Pack Sessions and Architecture
- More on Action Pack Partial Templates
- Action Pack Partial Templates
- Displaying Error Messages with the Action Pa...
- Action Pack Request Parameters
- Creating an Action Pack Registration Form

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2018 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials