Web Services in rails

Source: Internet
Author: User
Tags representational state transfer ruby on rails

Ruby on Rails is a suddenly popular framework that acts as a catalyst for the ruby programming language. As Ruby experiences continue to succeed, developers began to seek to integrate their ruby applications with applications written in other languages. Rails provides excellent support for Web Services. This article introduces the Web service in rails, focusing on a policy named representational state transfer (rest.

Over the past 20 years, a trend has dominated the development of commercial software tools: Dealing with complexity. This trend is no more obvious anywhere than in the distributed computing field. The C and Java communities have seen some incredibly complex frameworks built to support distributed communication. The distributed computing environment (DCE) supports remote process calls between applications written in C language. The Common Object Request proxy architecture (CORBA) standard supports communication between object-oriented applications. Enterprise JavaBean (EJB) specifications provide security, persistence, transactions, messages, and remote services. The promotion of various frameworks is rampant, but these frameworks have not met expectations, and some have even become disasters due to their complexity. Among these frameworks, only EJB 3.0 is a result of great simplification and has the potential to succeed in distributed applications. The market may or may not provide another space for the Framework facing a strong competitor, but EJB still needs to be delivered and used.

The latest large-scale distributed framework is Web Services. Web Service technology allows applications to communicate with each other in an independent platform or programming language. Web service standards are also threatened by complexity demons, but the alternative strategy called rest promises a simpler approach. This article describes how to add restful Web Services in Ruby on Rails and call services from Ruby and Java code.

  Web Services

Like EJB, CORBA, and DCE, the core abstraction of Web Services is also Remote Process calling. Web services use a protocol called soap (initially, soap represents a Simple Object Access Protocol, but this term is now downgraded) to represent the structure of a message in XML. Here is a tip: if the protocol is used to represent a simple s, it is not simple. The Web Service Definition Language (WSDL) provides standard standards for services. Like SOAP, WSDL is also a tricky and complex API, and soap and WSDL only cover the surface of the numerous APIs that constitute the big monster of Web Services. The Web Service requires an overhaul. Thanks to Roy Fielding's influential doctoral thesis, the Web service has been overhauled.

Fielding's thesis describes the rest application networking strategy. Rest is fundamentally different from full-stack Web Services for three reasons:

  • The core abstraction of rest is remote resources rather than remote process calls.
  • Rest does not create a detailed list of standards, but uses existing Internet standards, including HTTP, XML, and TCP/IP.
  • Rest does not cover every possible scenario, but covers the most common problems.

Think of rest as a browser. Rest users use the same HTTP command as the browser to access resources. When a rest customer accesses a resource, the customer switches to a State. With different HTTP commands, rest customers can create, read, update, or delete resource records.

For example, a typical blog is used as an example. Enter a URL, such as blog.rapidred.com, to obtain the list of posts. Then, if you want to edit a blog entry, you can enter an HTTP parameter in the URL (for example, blog.rapidred.com/edit? Article = 12345), and then the edit form is displayed. Because each blog entry has its own URL, you can click the link or directly enter the URL to read, modify, or delete the content using the HTTP command.

In short, rest can:

  • Use TCP/IP naming standards to name Web Resources
  • Use http to query and manipulate these resources
  • Construct Data Using text-based standard message formats (such as XML or HTML)

Ruby on Rails uses rest to provide excellent support for Web Services.

 

 

  Action Web Services Overview

Rails uses a module called Action web services to implement web services. Many development frameworks encourage views and web services to use independent controllers. This policy can maintain consistent styles between controllers. The problem is that a new controller is required for each type of service. For example, the Ajax user interface requires remote XML calls from the Controller to JavaScript.

You do not have to assign a specific controller to the web service. Using rails, you can use the same controller to provide content to HTML-based views, XML-based Web Services, and XML-based JavaScript components. The best way to understand Action web services is to view its actual effect in the working application environment.

Create a database named service_development using the selected Database Manager. Next, run the following command to create a rails project and model:


> Rails Service
> Script/generate Model Person

After the model is generated, a migration called dB/migrate/001_create_lele.rb is available. Please make this migration the same as editing imaging List 1:

List 1. Migration of the people table

Class createpeople <activerecord: Migration
Def self. Up
Create_table: people do | T |
T. Column: first_name,: String,: Limit => 40
T. Column: last_name,: String,: Limit => 40
T. Column: email,: String,: Limit => 40
T. Column: Phone,: String,: Limit => 15
End
End

Def self. Down
Drop_table: People
End
End

Modify the database configuration in config/database. yml to match with your own database configuration, and enter rake migrate. Finally, enter script/generate scaffold person people to generate a workbench for the person model and people controller. Now you can start the server with script/server. Point your browser to localhost: 3000/people to see the typical rails scaffolding for person. Figure 1 shows the applications with standard rails scaffolding:

 

Figure 1. Simple rails Application


 

 

If you have followed the Ruby on Rails project of this series, you will know that the general process of the typical Controller method is:

  • 1. the user sends a request through HTTP by following the link or specifying the URL.
  • 2. The Web Server transfers requests to Ruby on Rails based on the domain configuration.
  • 3. the rails router routes requests to the controller according to the URL mode. The default mode is http: // host name/controller/Action/parameter.
  • 4. the router calls the method on the controller with the same parameters as the action.
  • 5. The action parameter sets instance variables for the view and displays the view.
  • 6. The action method copies the instance variables to the view.

For example, see the show method in Listing 2. The @ person instance variable used by the Controller to set the view. Because the method does not specify the view name, rails calls the view with the same name as the controller action-in this example, the view is located in APP/views/people/show. rhtml.

Let's look at the list method. If you want this method to render XML, You need:

  • Delete pages
  • Convert people instance variables to XML
  • Rendering XML instead of HTML

Rails makes it possible to process Web Services and present views from the same web service. In fact, no paging is required. To simplify the list method of web services, you can change the list method in the Controller to clear pages like listing 3. You also need to delete the "next page" and "Previous Page" Links near the APP/views/people/list. rhtml code.

Listing 3. simplified list

Def list
@ People = person. find_all
End

Because the page is deleted, a feature that makes the user interface more robust is deleted, but some results are returned. The same Code can be used to drive web services and views. If you need paging in the future, you can write custom assistants.

Now that the basic application is available, you can add some Web Services.

 

 

  Add web services to the rails Controller

If I want to talk about it, I can say "a web service already exists ". Remember what I said to rest? This style of Web Services uses specified resources. My rails application also has the specified resource: host_name/people/list to call my list service. Rest-style Web Services also use TCP/IP and HTTP. This is what my rails application does. The well-formatted HTML is a subset of XML and meets the last rest requirement. You only need to call http get on localhost: 3000/people/list and parse the result to get the personnel list. This is the key. Rest works in the same way as Internet. But this is not really a rest-based Web service. Ideally, XML documents that reflect the meaning of person should be provided, rather than the structure of the user interface.

A real service should produce a pure data representation, a representation built specifically for the expected customers of the service. However, the sample application has two clients: end users and rest users. To reuse the same code for two purposes, you need to provide more information to rails. Rails designers may decide to use additional URL parameters, but it is a hard task to process URLs. Rails should not use these details to increase user burden. On the contrary, HTTP provides a tool to specify more information: HTTP header.

It is helpful to understand the rest model of Web Services and understand HTTP. Curl (think of it as a view URL) command allows a command to query a URL and view the response. The UNIX-based operating system contains curl by default. You can download the free curl tool for other operating systems. By entering curl http: // some-URL, you can limit the request to only output the default response body (HTML rendered by the browser ). Enter curl-I http: // some-URL to obtain more information. This command returns the HTTP header, as shown in Listing 4. The header configuration is composed of key-value pairs that indicate the configuration of each request.

Listing 4. Using curl to call HTTP requests

> Curl-I http: // localhost: 3000/people/List
HTTP/1.1 200 OK
Cache-control: No-Cache
Connection: keep-alive
Date: Tue, 27 Jun 2006 14:54:49 GMT
Content-Type: text/html; charset = UTF-8
Server: webrick/1.3.1 (Ruby/1.8.4/2005-12-24)
Content-Length: 854
Set-COOKIE: _ session_id = 216912045de52786f032b22755c903dd; Path =/

The http get, put, post, and delete commands are frequently displayed later. Rest uses some commands to execute the typical CRUD (crud is the abbreviation of create, read, update, and delete ). The cring from the HTTP command to crud is as follows:

  • Create (create): HTTP PUT
  • Read: HTTP GET
  • Update: HTTP POST
  • Delete: HTTP Delete

The browser uses the HTTP header and uses the same server code to meet different types of requests. Well-performing applications provide sufficient information to properly process documents. One piece of information is called the HTTP accept header. With more effort, the controller can use some assistants and use the accept header to determine how to respond to incoming requests. Then, the controller can display the appropriate response. Change the list method in peoplecontroller to the same as listing 5:

Listing 5. extend the list method to render XML

Def list
# Wants is determined by the HTTP accept header in the request
@ People = person. find_all
Respond_to do | wants |
Wants.html
Wants. xml {render: xml => @ people. to_xml}
End
End

 

In listing 5, you can see the complete rest-based Web service. The generated code is a beautiful example of a small and medium-sized rails domain-specific statement. It extends Ruby to construct a switch statement. It works like this:

  • 1. The respond_to method accepts a single code block and passes an instance variable (marked as wants) to the code block.
  • 2. Wants has a method for each possible type. The controller can specify a code block for each type that the controller expects.
  • 3. If the method name matches the type in the HTTP accept header, the wants method executes the corresponding code block.
  • 4. If no code block is specified (such as wants.html), rails executes the default action (in this example, the APP/views/people/list. rhtml is displayed ).

This policy allows all expected customers to share the same setup code. To add the Javascript client of the expected HTML to make the application support Ajax, you only need to add wants. JS, as shown in Listing 6:

Listing 6. Rendering HTML for JavaScript customers


Def list
# Wants is determined by the HTTP accept header in the request
@ People = person. find_all
Respond_to do | wants |
Wants.html
Wants. js
Wants. xml {render: xml => @ people. to_xml}
End
End

Now we can see how to add the rest web service to the read-only method. The show method is similar, as shown in listing 7:

Listing 7. Implement show

Def show
@ Person = person. Find (Params [: Id])
Respond_to do | wants |
Wants.html
Wants. xml {render: xml => @ person. to_xml}
End
End

You may have noticed that only read-only services are available through rest. The reason is that less work is required to submit and delete applications. No additional support is required for deletion, because the ID of the person to be deleted has been specified by the URL in the current Code. Rails automatically converts the XML entered in the POST request, so no server support is required. In fact, applications can be deleted, updated, and created without being changed. You can fix the HTTP response presented by each method, but the customer code is actually after the HTTP return code.

Now is the time to call the web service.

 

  Call Web Services

Using the existing HTTP protocol policy makes the call simple. Listing 8 shows the ruby version. Note the HTTP accept header. Remember, the Controller determines the content type based on this header.

Listing 8. Calling services from Ruby


Require 'net/http'

Net: http. Start ('localhost', 3000) Do | HTTP |
Response = http. Get ('/people/list', 'accept' => 'text/xml ')

# Do something with the response.

Puts "code: # {response. Code }"
Puts "message: # {response. Message }"
Puts "Body:/N # {response. body }"
End

The Web service call in listing 8 calls the http get Method on http: // localhost: 3000/people/list and outputs a response. Ruby has a good library to process the generated XML, but they are beyond the scope of this article. You do not need to use Ruby to call this service. Only the HTTP library is required. Listing 9 shows the Java calls of this service:

Listing 9. Using Java code to call a service

Package com. rapidred. ws;

Import java.net .*;
Import java. Io .*;

Public class simpleget {

Void get (){

Try {
URL url = new URL ("http: // localhost: 3000/people/List ");
Urlconnection = URL. openconnection ();
Urlconnection. setrequestproperty ("accept", "text/XML ");
Bufferedreader in =
New bufferedreader (New inputstreamreader (urlconnection. getinputstream ()));
String STR;

While (STR = in. Readline ())! = NULL ){
System. Out. println (STR );
}

In. Close ();
}
Catch (exception e ){
System. Out. println (E );
}
}

Like its Ruby equivalents, this code opens a URL Connection, sets the accept header to text/XML, sends out get, and outputs the result. Java code has many XML frameworks, but I hardcoded XML in this example to keep the example simple.

 

The call to post is similar. Listing 10 shows a simple post:

Listing 10. Using Java code to call HTTP POST


Void post (){
Try {
String xmltext = "<person>" +
"<First-name> Maggie </first-name>" +
"<Last-name> Maggie </last-name>" +
"<Email> maggie@tate.com </Email>" +
"</Person> ";

URL url = new URL ("http: // localhost: 3000/people/create ");
Httpurlconnection conn = (httpurlconnection) URL. openconnection ();
Conn. setdooutput (true );
Conn. setrequestmethod ("Post ");
Conn. setrequestproperty ("Content-Type", "text/XML ");
Outputstreamwriter wR = new
Outputstreamwriter (conn. getoutputstream ());
Wr. Write (xmltext );
Wr. Flush ();

Bufferedreader RD = new bufferedreader (New
Inputstreamreader (conn. getinputstream ()));
String line;
While (line = RD. Readline ())! = NULL ){
System. Out. println (line );
}
Wr. Close ();
Rd. Close ();
} Catch (exception e ){
System. Out. println ("error" + E );
}
}

This http post calls post on http: // localhost: 3000/people/create, passes an XML document in the HTTP document body, and creates a new person. (Generally, XML documents should be constructed using the Java XML library. This time I hardcoded the XML document to keep the example simple .) Rails supports automatically converting the entered XML into a ruby hash list of the person attribute.

  Conclusion

In this article, we have seen that the Controller supports rest-based Web Services with only a small amount of code. Dynamic Internet statements, such as Ruby, use rest to replace soap-based Web Services. Some simple calls, including the beautiful responds_to syntax and automatic XML Conversion for incoming submissions, make it easy to use the same controller to process Web Services, remote JavaScript requests, or HTML.

The Java language also provides excellent support for rest. After all, servlet is actually a rest-based Web Service on the server. Servlet can be used in Java, rails controller can be used in Ruby, and applications that take advantage of the two platforms can be combined. This is the beauty of Web Services. Everything you really need is superior courage.

 

View Original

 

View the Controller code before I introduce Rails Web Services. Edit APP/controllers/people_controller.rb to match the code in Listing 2:

List 2. Controller code of eaglecontroller

Class peoplecontroller <applicationcontroller
Def Index
List
Render: Action => 'LIST'
End

# Gets shoshould be safe (see
Http://www.w3.org/2001/tag/doc/whenToUseGet.html)
Verify: method =>: Post,: Only => [: Destroy,: Create,: Update
],
: Redirect_to =>{: action =>: list}

Def list
@ Person_pages, @ people = paginate: People,: per_page => 10
End

Def show
@ Person = person. Find (Params [: Id])
End

Def new
@ Person = person. New
End

Def create
@ Person = person. New (Params [: person])
If @ person. Save
Flash [: Notice] = 'person was successfully created .'
Redirect_to: Action => 'LIST'
Else
Render: Action => 'new'
End
End

Def Edit
@ Person = person. Find (Params [: Id])
End

Def update
@ Person = person. Find (Params [: Id])
If @ person. update_attributes (Params [: person])
Flash [: Notice] = 'person was successfully updated .'
Redirect_to: Action => 'show',: Id => @ person
Else
Render: Action => 'edit'
End
End

Def destroy
Person. Find (Params [: Id]). Destroy
Redirect_to: Action => 'LIST'
End
End

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.