10
Create RESTful Applications

“Rest, the sweet sauce of labor.”

—Plutarch

What Is REST?

Service-oriented architecture (SOA) and development is a paradigm where software components are created with concise interfaces, whereby each component performs a discrete set of related functions. Each component, with its well-defined interface and contract for usage, can be described as providing a service to other software components. This is analogous to an accountant who provides a service to a business, even though that service consists of many related functions (i.e., bookkeeping, tax filing, investment management, and so on).

With SOA, there are no technology requirements or restrictions. You can build a service in any language with standards such as CORBA, platform-specific remote procedure calls (RPC), or the more universally accepted XML. Although SOA has been around as a concept for many years, its vague definition makes it difficult to identify or standardize upon. The client/server development model of the early 90s was a simple example of an SOA-based approach to software development.

A Web service is an example of an SOA with a well-defined set of implementation choices. In general, the technology choices are the Simple Object Access Protocol (SOAP) and the Web Service Definition Language (WSDL), both XML-based. WSDL describes the interface (also called the contract), whereas SOAP describes the data that is transferred. Because of the platform-neutral nature of XML, SOAP, and WSDL, Java tends to be a popular choice for Web service implementation due to its OS-neutrality.

Web service systems are an improvement of client/server systems, and other proprietary object models such as CORBA or COM, because they’re built to standards and are free of many platform constraints. Additionally, the standards, languages, and protocols typically used to implement Web services helps systems built around them to scale better.

Representational State Transfer (REST)

However, there exists an even less restrictive form of SOA than a Web service. This style of architecture is called representational state transfer (REST), as labeled by Dr. Roy Fielding in his doctoral dissertation. REST is a collection of principles that are technology independent, except for the requirement that it be based on HTTP, the protocol of the World Wide Web. In short, a system that conforms to the following set of principles is said to be RESTful:

•   All components of the system communicate through interfaces with clearly defined methods and dynamic, mobile, code

•   Each component is uniquely identified through a hypermedia link (i.e., URL)

•   A client/server architecture is followed (i.e., Web browser and Web server)

•   All communication is stateless

•   The architecture is tiered, and data can be cached at any layer

These principles map directly to those used in the development of the Web and, according to Dr. Fielding, account for much of the Web’s success. The HTTP protocol, its interface of methods (GET, POST, HEAD, and so on), the use of URLs, HTML, and JavaScript, as well as the clear distinction between what is a Web server and a Web browser, all map directly to the first four principles. The final principle, regarding tiers, allows for the common network technology found in most Web site implementations: load balancers, in-memory caches, firewalls, routers, and so on. These devices are acceptable because they don’t affect the interfaces between the components; they merely enhance their performance and communication.

The Web is the premier example of a RESTful system, which makes sense since much of the Web’s architecture preceded the definition of REST. What the Web makes clear, however, is that complex remote procedure call protocols are not needed to create a successful, scalable, understandable, and reliable distributed software system. Instead, the principles of REST are all that you truly need.

Overall, REST can be described as a technology and platform-independent architecture, where loosely coupled components communicate via interfaces over standard Web protocols. Software, hardware, and data-centric designs are employed to maximize system efficiency, scalability, and network throughput. The underlying principle, although never explicitly mentioned in any REST description, is simplicity.

REST differs from other software architecture in that it marries the concepts common to software architecture (interfaces, components, connectors, patterns, and so on) with those of network architecture (portability, bandwidth management, throughput measurement, protocol latencies, and so on). This combination makes REST ideal for distributed software systems where scalability in terms of both processing power and communication efficiency are critical.

Figure 10.1 illustrates the REST architecture in one comprehensive diagram that combines logical software architecture with physical network elements. For instance, it demonstrates the following REST principles:

•   Communication is performed over HTTP.

•   Clients contain optional server caches for efficiency.

•   Services can employ caches to back-end systems.

•   There are no restrictions on the number of clients per service, or the number of services per client.

•   Services can call services.

•   Load-balancing hardware is used for scalability.

•   Firewalls can be used for security.

Figure 10.1 Overview of REST Components

Image

In this diagram, the physical components have been shaded for clarification.

There are some interesting points on data caching that need to be made. First, data must be marked, either implicitly or explicitly, as cacheable or non-cacheable. Second, although specialized caches may be used (custom, in-memory data structures), general-purpose caches, such as Web browser caches, or third-party Web caches (such as Akamai) may also be used.

Building a RESTful System

If you eliminate typical Web service protocols (XML-RPC SOAP, WSDL, and so on), how do you build an SOA-based RESTful system? With REST, you use the same mechanism used to request a Web page: the HTTP query URL. For instance, take a look at the sample SOAP call in Listing 10.1. Here, a request is made for an employee’s benefits information from a human resources Web service.

Listing 10.1 Sample SOAP Call

Image

With REST, you can replace a SOAP call, such as that shown in Listing 10.1, with the following URL:

Image

The HTTP query URL definition is all you need to know and use to make calls to a RESTful service. The response can be HTML, comma-delimited data, XML, JavaScript Object Notation (JSON)—which we’ll explore in the next section—or a more sophisticated document type such as a spreadsheet.

REST Response Types:

Image

Some feel that the return of anything but hypermedia-based content is not truly RESTful. However, in our opinion, as long as the system stays true to the REST principles for the request and the communication protocol, the response type is unimportant.

When you build a Web application with a Java Servlet, for example, it’s straightforward to read the data passed through URL query parameters, and to return any text-based response to the caller. The Java Servlet doPost method implementation in Listing 10.2 illustrates this. Here, the parameters used in the HTTP query URL above are read and used to retrieve a user’s employee benefits. The results are encoded as human-readable text. Because this is an example of a RESTful service, the request can be initiated—and the response viewed—by a Web browser, or any component in a distributed application.

Listing 10.2 Java Servlet doPost

Image

For the remainder of this chapter, we’re going to focus on consuming RESTful services from a JavaFX application. In particular, we’re going to examine just how straightforward it is to request and consume Web service data in both JSON and XML formats. First, let’s take a closer look at the details of JSON.

JavaScript Object Notation (JSON)

With the emergence of dynamic Web-based applications based on Asynchronous JavaScript and XML (Ajax) technology, JavaScript Object Notation (JSON) became a popular alternative to XML. This is mainly because JSON tends to be smaller and more readable than XML, making it both more efficient to send over the Internet uncompressed, and more convenient to work with. Although it’s closely associated with JavaScript—in fact it’s a subset—in practice it’s language independent.

There are JSON parsers available for most of the popular languages, including C++, Java, Perl, Python, and now JavaFX. JSON’s basic object types, which map very well to both Java and JavaFX types, are

String. A Unicode text string of characters enclosed in double quotes, with backslash escaping.

Number. An integer, real, or floating-point numeric value.

Boolean. A flag that contains a true or false value.

Object. A collection of associated data, represented as key:value pairs, separated by commas, and grouped together with curly braces. For example:

Image

Array. An ordered pair of comma-separated values grouped together with square braces. For example:

Image

The value null is also valid. These types and structures were chosen because modern programming languages support them natively. For instance, Listing 10.3 shows a sample JSON object structure, named Image, as returned from Yahoo! Web Services.

Listing 10.3 Sample JSON Object

Image

This JSON data defines an Object (named Image) that contains two Number fields (named Width and Height), a String field (named Title), another Object (named Thumbnail), and an array (named IDs). The Thumbnail object contains its own String and Number fields, and the IDs array contains a series of Number values.

Let’s take a closer look at some Web services that are available publicly for you to use in your applications. The two we’ll discuss in this chapter, Yahoo! and GeoNames, both support JSON for many of their services. In the next section, we’ll build an application that combines these two Web services to form a mashup JavaFX application.

Yahoo! Web Services

Yahoo! offers a large number of Web service APIs that you can use to create your own applications; you can explore these Web services at http://developer.yahoo.com/everything.html. Although the APIs all support XML as a return type, a good number of them also provide JSON as an alternative (see http://developer.yahoo.com/common/json.html). By adding the output= parameter onto the request URL, you can specify XML or JSON as the response data type.

For instance, one Yahoo! service allows you to do image searches from your application. To make a request for, say, images from JavaOne with the results in JSON form, you can use the following URL:

Image

Here, we’ve specified the ImageSearchService, with the text JavaOne as the search query, and the output set to JSON. Another service that Yahoo! provides is called the LocalSearchService, which allows you to search for anything in a particular location. We’ll use this service in the sample JavaFX mashup application, discussed in the next section. However, let’s first take a quick look at the GeoNames Web service.

GeoNames Web Services

GeoNames provides a number of Web service APIs that return interesting data relevant to specific locations. For instance, there are services that provide weather data, Wikipedia data, earthquake data, and so on, for locations you specify. You can explore the full set of Web service APIs at http://www.geonames.org/export/ws-overview.html. Most of the GeoNames services support both XML and JSON as output.

For instance, you can look up weather by airport code (using an airport close to the location you want the current weather for) with the following URL:

http://ws.geonames.org/weatherIcaoJSON?ICAO=KJFK

Here, we’ve requested the JSON weather service specifically, and have provided the airport code JFK with a K as a prefix, per the service contract. Alternatively, you can request weather data for a specific location supplied as longitude and latitude data. We’re going to use this form of the weather service in the sample JavaFX mashup application. Let’s take a look at how to use JavaFX to call external Web services, and then parse the output.

JavaFX and REST

As of version 1.0, JavaFX includes two classes that allow you to easily build REST clients. These classes are javafx.async.RemoteTextDocument and javafx.data.pull.PullParser. With RemoteTextDocument (see Figure 10.2), you can asynchronously make an HTTP request to a URL that you provide. When the return document has been received, the onDone function, which you implement, is called with an indication of success or failure. Next, you can access the returned document through the RemoteTextDocument.document member variable. Listing 10.4 shows an example of these steps in action.

Figure 10.2 The RemoteTextDocument Class

Image

Listing 10.4 Using RemoteTextDocument

Image

When the requestData function is called, the act of creating a new RemoteText-Document instance with a valid URL starts the request process. When a document has been received successfully, the data is read in as a ByteArrayInputStream as it would with Java, and this step is complete. At this point, it doesn’t matter what the response type is; the job of the RemoteTextDocument class is to get the document to you.

However, if the returned document is XML or JSON, you’ll need to parse it to make use of it. This is where the PullParser class (see Figure 10.3) comes in, which is called in Listing 10.4, highlighted in bold type. There’s some more code behind this that you need to provide, such as the code in Listing 10.5. It begins with a custom class, Location, since this code illustrates parsing location data as received from Yahoo! Web Services.

Figure 10.3 The PullParser Class

Image

The real work begins with the object, parser, which is an instance of the Pull-Parser class. It begins parsing as soon as its input object is set and the parse method is called. Because it’s bound to the ByteInputStream object bis from Listing 10.4, it has access to the data as soon as the RemoteTextData object populates it. It’s this bound variable that allows the code in Listing 10.4 (which requests data from a remote server) to cooperate with the code in Listing 10.5 (which parses the received JSON document).

Listing 10.5 Using PullParser

Image

As PullParser progresses through the document, it fires a series of events (see Table 10.1) that are handled by your code in the onEvent function.

Table 10.1 PullParser Events to Process

Image

As shown in Listing 10.5, each time a value is completely parsed, the onEvent function compares the name to those that we’re interested in. If there’s a match, the value is simply stored. In this case, as location specific data is received, the code populates the Location object. With further use of object binding (which was discussed in Chapter 4, Synchronize Data Models—Binding and Triggers), it’s easy to envision how individual UI elements will be updated to display the location data—such as the city name—as the data is parsed in this code. In fact, the sample JavaFX application we’re going to explore in this section does just that. Let’s examine the complete sample application now, which shows the current weather conditions for any valid ZIP code entered.

The JavaFX Weather Widget

As an example of how to make use of RESTful services from a JavaFX application, we’re going to build a simple weather widget (shown in Figure 10.4). The widget accepts a ZIP code as input, and in turn displays detailed current weather conditions for the applicable region. This includes cloud conditions, wind speed and direction, temperature, humidity, and air pressure at sea level.

Figure 10.4 The JavaFX Weather Widget

Image

The widget’s GUI is a JavaFX scene that contains a group of three main components: title text, a progress bar, and a vertical box that contains the individual weather text components. Some of the code for this is shown in Listing 10.6. The progress bar remains hidden until a request is made to a REST service, at which point it’s made visible and is activated. When all of the requested data is received, it’s hidden again.

Listing 10.6 The Weather Widget Scene Structure

Image

Image

Each weather text field, which actually consists of two JavaFX Text fields—a label and value both arranged horizontally—are bound to variables that are updated with the latest weather data received from the GeoNames weather service. We’ll examine the data structure and request process later in the chapter. The entire weather request sequence is started when you enter a valid ZIP code and press the Return key. The weather widget can be considered a mashup application, as it uses data from both Yahoo! and GeoNames. Let’s take a closer look at this process now.

A Mashup Application

The weather widget first requests location data from Yahoo! Web Services with the ZIP code provided, then it makes a request to the GeoNames weather service with the returned location data. This four-step process is illustrated in Figure 10.5.

Figure 10.5 The Mashup Data Flow

Image

As data is received, and the bound data structure values are updated, the widget’s GUI is automatically updated to reflect the new data.

Using Yahoo! Web Services

Because the GeoNames service requires location data in terms of longitude and latitude to return local weather conditions, we use Yahoo!’s city search feature to get this data. The request is made, including the ZIP code entered, with the following URL in the JavaFX code:

Image

Being bound to the zipCode field, which is entered by the user, the string is updated automatically with its value when changed. This request returns location data for the ZIP code, as well as local search results that are limited to one result as specified in the URL. The only data we’re interested in, however, are the fields of the Location class, shown in Listing 10.7.

Listing 10.7 The Location Data Structure

Image

These fields are updated when the JSON names that match are located within the JSON text, as read by the PullParser class, locationParser (see Listing 10.8). Although many other fields and values are encountered while parsing the location data, only the four Location class values are stored.

Listing 10.8 The Location JSON Data Parser

Image

Being that the PullParser’s member variable, input, is bound to the location-Input variable, this code is invoked whenever the input stream is updated and the parse method is called. This occurs when the user enters a ZIP code and presses Return, as processed in the action function highlighted in bold typeface in Listing 10.6. After the location data is processed, the results are used in the request to the GeoNames service to receive the current weather conditions. Let’s take a look at this process now.

Using GeoNames Web Services

As mentioned earlier, the GeoNames service returns the current weather conditions by either a supplied airport code or location (longitude and latitude). For the weather widget, we want to make the request by location. The location data is used with the following JavaFX URL string to form the request:

Image

Being bound to both the Location.lat and Location.lng variables, the text is automatically updated with these values when they’re changed. The request returns detailed weather conditions that are stored in the fields of the Weather class, shown in Listing 10.9.

Listing 10.9 The Weather Data Structure

Image

These fields are updated when the JSON names that match are located within the JSON text, as read by the PullParser class, weatherParser (see Listing 10.10). Note that because some fields differ in their value types (i.e., String, Number, and Integer), Java classes such as Double and Integer are used to get the proper values from the JSON text.

Listing 10.10 The Weather JSON Data Parser

Image

As with the request to Yahoo! for the location data, since weatherParser’s member variable, input, is bound to the weatherInput variable, this code is invoked when the input stream is updated and parse is called. This is triggered when the location data is completely received. When all of the weather data is received, and the Weather class’ member variables have been set, the JavaFX Text components that are bound to them are automatically updated. This completes the weather widget’s request, update, and display processes. When compared to implementing the same functionality with plain Java code, the power of JavaFX object binding greatly simplifies the entire process.

JavaFX and XML

The weather widget application is a simple example of how to process JSON Web services, but what about XML? Consuming XML-based REST services is completely supported, and the code only changes slightly. The two main differences are

•   Document type: Set to PullParser.XML (instead of PullParser.JSON).

•   Use of javafx.data.xml.QName: XML node names arrive via this object, with namespace information, referenced from the Event object.

For instance, the code to parse the Yahoo! location data in XML form is shown in Listing 10.11. The two differences listed in the preceding are highlighted in the code in bold type.

Listing 10.11 Parsing XML

Image

The QName class is part of the javafx.data.xml package that also contains the XMLConstants class. This class contains the following standard XML constant strings:

XMLNS_ATTRIBUTE. Example: “xmlns”

XMLNS_ATTRIBUTE_NS_URI. Example: “http://www.w3.org/2000/xmlns/

XML_NS_PREFIX. Example: “xml”

XML_NS_URL. Example: “http://www.w3.org/XML/1998/namespace

XML_VERSION. Example: “1.0”

The remainder of the application code remains the same as the JSON version, presented earlier in this chapter. This makes parsing XML and JSON documents quite straightforward, with very little work to switch between the two.

Chapter Summary

This chapter illustrated how the JavaFX classes, RemoteTextDocument and PullParser, combined with the power of object binding make JavaFX applications ideal REST clients. In this chapter, we explored the creating of a widget that displays current weather conditions from the combination of JSON (or XML) data received from Yahoo! and GeoNames Web services. Thanks to the power of JavaFX, simple data structures bound to JavaFX GUI components and updated by classes provided by the JavaFX framework are all that’s required to create a working Web 2.0 mashup.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset