ben robison
when only more words will do
Howto: Put WSDL on Rails [Part 2]
In the first article about WSDL on Rails we created our own web service that accepted a string, modified it, and returned a new string. Now we’ll take a look at creating another application that can consume or subscribe to our web service. This is almost too easy. I figure the best way to demonstrate the simplicity is to keep this article as short as possible.
1. Fire up the old WebServiceProvider application that we created in Part 1
From the application root directory type ./script/server
2. Create a new WebServiceConsumer application
In a new terminal window type rails WebServiceConsumer
3. Create a controller for your service consumer
cd WebServiceConsumer
./script/generate controller consumer
4. Subscribe to your WebServiceProvider using its WSDL
Open up your consumer_controller.rb in app/controllers. It will be empty and it needs to look like this:
class ConsumerController < ApplicationController
require 'soap/wsdlDriver'
def subscribe
if params[:terms] == nil
@service_output = “”
else
url = “http://localhost:3000/subscription/service.wsdl”
factory = SOAP::WSDLDriverFactory.new(url)
service = factory.create_rpc_driver
@service_output = service.Subscribe(params[:terms])
end
end
end
This is where the magic happens. The line require 'soap/wsdlDriver' brings in the needed Ruby library. The subscribe method is simply an action like any other in your application. We’re going to create a form that accepts some user input and then we’ll pass them on to our WebServiceProvider. The url, factory, and service lines could all be done in one line, but I’ve broken them out here to demonstrate.
If the box is left blank, we don’t do anything. If the user inputs some data, then we have a little bit of work to do. We create a new service object based on the WebServiceProvider’s description of itself as defined by its WSDL. Then our local service object acts as a proxy and any method calls we make on the local object are simply passed on to it the actual WebServiceProvider.
We can then define our @service_output as a variable we can then call in our view. Now for testing.
5. Create two views for testing
In app/views/consumer create an index.rhtml file as follows:
<html>
<head>
<title>WebServiceConsumer</title>
</head>
<body>
<h1>WebServiceConsumer</h1>
<p>
Enter your terms below. They will be passed on to our web service and you'll be able to see the response.
</p>
<%= start_form_tag :action=> 'subscribe' %>
<p><label>Terms</label><br/>
<%= text_field 'terms', '' %></p>
<%= submit_tag "Subscribe" %>
<%= end_form_tag %>
</body>
</html>
Also in app/views/consumer create subscribe.rhtml as follows:
<html>
<head>
<title>WebServiceConsumer</title>
</head>
<body>
<h1>WebServiceConsumer</h1>
<p>
The web service returned: <br /><br />
<%= @service_output %>
</p>
</body>
</html>
6. Now fire up your WebServiceConsumer app on a different port
Depending on your particular setup this may be different. I use lighttpd, so you’ll need to open app/config/lighttpd.conf and change the server.port = 3000 to say something like server.port = 3100. Then you can run ./script/server to fire up your app on port 3100.
Now point your browser to http://localhost:3100/consumer
Enter your terms into the text box, click Subscribe, and pat yourself on the back. You’ve just subscribed to a web service.
Howto: Make a Rails Environment in Ubuntu
In class today, there was a demonstration on how to get Apache/Axis/Tomcat running to demo some SOAP web services written in Java. As I plug Rails again, I was again amazed at the simplicity with which Rails handles all this. I began to think that there might be some interest in Rails web services for those other members in my class, so in an attempt to help them out, I decided to provide instructions on setting up a Ruby on Rails environment.
Now I’m running mine inside a virtual machine with VMWare Server on my Windows Server 2003 box. I won’t get into all the reasons here, but these intructions would work for any VM or for a real install as a host operating system. There are only one or two differences and I’ll point them out as we go along.
1. Start with Ubuntu Server distro. I’m using Ubuntu 6.10 Edgy Eft.
Find the mirror you want, then click the Other Installation Options and find the server. If you must have a graphical environment, you can get the desktop version, but know that youll have to install apache2 and mysql on your own. If you choose the server option, you’ll be asked what kind of install you want to do. Pick the LAMP option. Do all appropriate setup, naming, networks, etc., and I’ll meet you again at the shell after you login.
2. Edit your sources list.
sudo vi /etc/apt/sources.list
Once you get inside, you’ll want to uncomment 4 lines, which will enable the universe repository along with the security universe repository. I typically comment out the cdrom: repository as well. For those unfamiliar with vi, the letter x will delete a single character. Pushing the letter i will put you in insert mode to comment our the cdrom line. Pushing Esc will get you out of edit mode. Pushing :, then wq, and finally Enter will put you back at shell with an edited sources list.
3. Get SSH running
For me this is essential. The interface through VMWare isn’t the speediest thing, and when you’re running over a Remote Desktop connection, things start to feel like molasses. A few things will fix us right up, because through SSH everything runs beautifully.
sudo apt-get install openssh-server
This will install and start the SSH server. Now you may need to configure port-forwarding through port 22 in order to connect to your Rails/Ubuntu server. In addition if you need to forward traffic to your VM, then at your router point port 22 at the host OS and follow my other instructions on port forwarding to a virtual machine.
If you’re happy where you’re at, then you can skip step 3. If you want to do it, then SSH to your new server and continue to Step 4.
4. Update all your packages
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install saidar
Saidar is optional, it’s a neat little monitoring utility that runs at the command line, but tells you about your CPU usage, memory usage, disk usage, and everything else you’d expect from your Task Manager or Activity Monitor. Now it’s time to get down to business.
5. Install Ruby
sudo apt-get install ruby ruby1.8 ruby1.8-dev ri rdoc irb libmysql-ruby libmysqlclient15-dev
If you didn’t choose the LAMP option earlier (or picked a desktop distro) you’ll want to add Apache2 and mysql-server to this list:
sudo apt-get install ruby ruby1.8 ruby1.8-dev ri rdoc irb libmysql-ruby libmysqlclient15-dev apache2 mysql-server
6. Install RubyGems
RubyGems is like the apt-get utility for strictly Ruby packages. This series of commands at the shell will download, install, and clean up the RubyGems package.
wget http://rubyforge.org/frs/download.php/11289/rubygems-0.9.0.tgz
tar -xvzf rubygems-0.9.0.tgz
cd rubygems-0.9.0
sudo ruby setup.rb
cd ~
rm -rf rubygems-0.9.0
rm rubygems-0.9.0.tgz
7. Install Rails
sudo gem install rails --include-dependencies
This will show some errors while installing documentation, but never fear. All is well. We both know that you weren’t planning on reading the documentation anyway.
8. Install Lighttpd with FastCGI
sudo apt-get install lighttpd libfcgi-dev libfcgi-ruby1.8 build-essential
This will show an error that it tried to bind to port 80 and failed. That’s ok, because we have apache running there. What we’ve done is simply install it so that our Rails apps will use Lighttpd rather than the built-in WEBRick.
If like me you really just don’t like errors you can edit the lighttpd.conf file so that it binds to a different port. This is not necessary at this point, but if you plan on running Rails apps in production you’ll have to play with the lighttpd config file at some point anyway.
vi /etc/lighttpd/lighttpd.conf
Find and uncomment the line that says
# server.port = 81
Now we’ll run Stop just to make sure and then Start it up again.
sudo /etc/init.d/lighttpd stop
sudo /etc/init.d/lighttpd start
Now install the fcgi RubyGem:
sudo gem install fcgi
9. Make sure that your FastCGI bindings and MySQL bindings are working properly.
Now to make sure that our fastcgi and mysql libraries are working properly, we’ll fire up IRB. IRB stands for Interactive Ruby. It basically gives us a functional, yet empty ruby environment to play around.
irb
irb(main):001:0> require 'mysql'
=> true
irb(main):002:0> require 'fcgi'
=> true
Now, unless you want to do all your mysql configuration from the command line, you’ll need to be able to connect as root to your mysql database from a remote host. See my instructions on how to do that. You may need to set up port forwarding through port 3306 in order to get this to work.
Howto: Put WSDL on Rails
Why do I love Rails so much? Because there is so much to love! Who ever dreamed that creating web services could be so simple? Where other frameworks can consume them very simply, Rails defines simplicity when it comes to creating them. Consuming them is easy as well, but it’s on the creation side that Rails really stands out from the competition. So how do you do it?
First off, let me say that my inexperience in web services means that I’m far from a subject matter expert. I can however follow simple instructions, and I found a beautiful set over at the SOA Ranch. This is a 3 part series, though more are supposedly coming. I hope these articles continue to be published, but I have my doubts as the most recent articles are nearly 6 months old now. The first one I found was part 3 part 2.5 in the series, and you can follow the links back to part 1 & part 2.
So let’s get down to business. I’ll make the assumption that you’ve got a working Rails environment. For Mac users, the latest version of Locomotive has everything you need for creating web services. For everyone else you’ll have to make your Rails environment the old fashioned way, although you can look forward to Rubuntu soon. We’re going to create a very simple web service that accepts a string, changes it a bit and returns a string.
First create yourself a new application
rails WebServiceProvider
Then you’ll want to open your application in your favorite Rails editor. Then we need to generate your web service.
./script/generate web_service Manipulation manipulate
This will create an API file for us to define our web service’s interface. It also creates a controller for us to use, and then a test file for us to use later (we won’t get to scripted testing in this article, although we will test it manually to prove that it works).
Now open up your manipulation_api.rb file in app/apis. You’ll see the following line of code that is the beginnings of our string manipulating web service.
api_method :manipulate
We’ll need to define parameters and data types for our method like so:
api_method :manipulate, :expects => [:string], :returns => [:string]
There are many data types that can be used here, but we’re keeping things easy for now. Now we’ll go look at the ManipulationController at app/controllers/manipulation_controller.rb. Because we followed the standard Rails naming conventions the mapping of the web service to the controller is already done, but if we hadn’t, this mapping can be done explicitly by adding the following to our controller.
web_service_api ManipulationApi
We can also give our web service a different name with the wsdl_service_name directive
wsdl_service_name 'Manipulation'
Notice also that in the controller is where we define all our logic for what happens with the parameters being passed in by our web service consumer. the manipulate method has already been created for us, so we simply need to tell our method to accept a string, perform our logic, and return another string.
Again we’ll keep things simple.
def manipulate(terms)
return "Yeah! " + terms + "!"
end
Now for all intents and purposes, our web service has been coded. We’ll add one more line to our controller that will generate a web front-end for the service so we can go see how it looks on the browser end. Just add the following line to your controller.
web_service_scaffold :invoke
Now let’s turn on the server and see how things look. Back at the terminal type
./script/server
Open your browser and point it to http://localhost:3000/Manipulation/invoke. This shows us the web view of our API. Follow the manipulate link to see the auto-generated web form that will show us what our service looks like. Type your message into Param0 box and click the invoke button to see all your beautiful web service XML. Another important point for those wishing to consume your web service is that Rails is automatically generating your wsdl for you. You can see how this works by checking the routes.rb file in app/config but just know that visiting http://localhost:3000/Manipulation/service.wsdl you can see the WSDL file that others will need to use your web service. You can use something besides service.wsdl by editing your routes.rb file appropriately.
Now this is obviously a simple example, but it illustrates the basic steps and important points. You probably wouldn’t have much use for a web service that adds the word “Yeah” and a few exclamation points to some user-input, but if we were doing this in the context of a real web application, you can start to imagine the possibilities available in your controller if you’ve got a dynamic database-driven application to work with. You can add other methods to your API, define the param and return types there, then define the logic in the controller in the appropriate method. Once you get the basics down, you’re on your way and the sky is the limit. Good luck developing your first piece of the Web 2.0.
Web Services [Part 2]
I wrote a few days ago about web services. Those writings were based on some preliminary research and class discussions. Since then I’ve had a little spare time to sit down and play them a bit, and even was able to whip up my own little web service in Rails. I’ll provide a HowTo as another article, but wanted to give my definition a bit of a refinement after some personal experience.
Any programmer is familiar with the concept of invoking a method on an object. For the non-programmers in the crowd, an object is simply something that us programmers use to represent real-life objects. When you register for my web site, give your email address, name, and password, I create a user object that represents you. When you come back to my website and login, I talk to your user object and ask it if the password you typed in is the right password. If it says yes, then I let you in, and if it says no, I tell you to try again.
In a traditional computer program or web application, we always have to create our own objects from our own data. Web services are changing that traditional model and changing the way we think about programming. In a larger sense this realignment of thought is changing the underlying structure of the web. It is changing the way that companies think about eCommerce. It is changing the fundamental make-up of the web itself. If you’ve heard about the Web 2.0, this is a very simplified description of that concept. For more about the Web 2.0 you should look up what O’Reilly wrote about the subject.
Web Services Redefined
So now that I’ve got the preliminaries out of the way, I’m going to explain web services much more simply than I did a few days ago. Web services simply provides a way for you to access and talk to objects that other people have written. More importantly, it doesn’t matter what programming language or platform that someone else used to create the service, you can use it with any platform you want to. That’s really all there is to it.
What About Web Services…
No doubt you’ve heard about web services, but what exactly are they? I’ve had teachers and others try to get this into my brain for at least the last three years, but it was only lately in a discussion about service-oriented architecture that it finally began to make sense. Let me lay these two topics out as simply as I can to see if I can make sense of it.
One of the problems with defining web-services is that has many different meanings to many different people. Don’t believe me? Type “define:web services” into your nearest Google search box to see what I mean.
So What Are They?
To get a better sense for what web services actually are, let’s first briefly discuss service-oriented architecture or SOA. The concept of SOA is not new, rather it is the context in which we use it that is new and improved. Very simply, the idea is that a piece of information or a particular process is exposed to consumers as a service. These consumers can be end-users or other services attempting to organize or “orchestrate” individual services into something an end-user can use.
Some people believe that web services is simply a new term for something that we’ve been doing for years. In a way this is true, and I’d bet that you interact with them more often than you realize, but it seems like it’s nothing new. Your computer runs dozens of services, each doing something important. What’s different about web services?
Let’s say that you have a web-service that looks up the weather, one that plots an address on a map, and one that finds the nearest gas station. An end-user can look up each of these individually or they can use an intermediate service that integrates each of these individual services and provides a single point of interface for all three pieces of information.
Abstracting out one more level, this intermediate service can be described as a so-called “portlet.” Think of a portlet as a widget; one piece of information that can be displayed along with many others and can be changed at will. The best example of this I can think of is your customized Google Homepage. You can choose from any number of portlets or widgets that will display many different kinds of information. When you login, requests are submitted to each individual portlet and the proper information comes back and is displayed in your browser.
How Does It Work?
I won’t get into incredible detail here, as the purpose is simply to provide an overview, but as Strong Bad says, “Technology is another word for magic.” Actually, there are some very basic technologies at work here. Each web service must simply describe itself with Web Service Description Language (WSDL) so that service consumers know what the service does and how they can interact with it.
Interaction happens through Simple Object Access Protocol (SOAP) and eXtensible Markup Language (XML). In very simplistic terms, SOAP is simply an extenstion to the HTTP protocol that enables the passing of parameters via a standard request/response interface. These parameters are passed in a standard XML format so that both sides can properly encode and decode the actual data being passed back and forth.
Why Web Services?
This now lets us as answer the question of why? Web services are language and platform agnostic, meaning that because the paths of communication are so stricly defined, that as long as a programming language or platform can speak the communicate in this common way, the two can communicate.
The other important “why” is that it cuts down costs. Before service-oriented architecture came along, if you had five proprietary systems that needed to communicate, each system had to define a custom interface to the other 4 in order to communicate. This means ten different interfaces would need to be programmed if all five want to talk, but if all speak the common language of services, then only five must be written. The business case for service-oriented architecture? Reduced cost.
Welcome to the Web 2.0.
Subscribe to RSS