Chapter 7. Web Services – At Your Disposal

Nowadays, all web applications have to connect with external services. Delegating difficult or complex computations to them or interacting on a social network are just some examples among thousands. Indeed, this means that our application can focus on what it is built for and it will ask other applications for specific needs.

This leads to the SOA architecture, which is more prone to the separation of concerns among services that have a clean and simple definition. A web service is one such dedicated service but is available online. In this chapter, we will discuss how to integrate a Play! Framework 2 application with such an architecture involving web services.

This kind of distributed architecture can lead to some problems because it relies on remote services, which most of the time don't have guaranteed SLAs. So they might block the server until a response is given or a timeout has occurred; meanwhile, other users who could have sent requests to the server will be queued.

For such cases, Play! Framework 2 comes with non-blocking helpers that will ease the work with long or potentially long tasks. This is mainly based on the underlying Akka system. To demonstrate this, we will cover the following points:

  • Get the big picture of the Web Service API
  • Access the Twitter API as a web service serving tweets in the JSON format
  • Update the dashboard to integrate the Twitter Web Service which adds external information about the content
  • Explain how to use web services in a reactive fashion, even if they are inefficient

Accessing third parties

In this section, we'll see how we can access remote services through HTTP using the Web Service API (WS API) that Play! Framework 2 has defined for our use.

A web service can have several meanings, such as access to certain resources or functionalities, but it can also have completely different architectures and data representations, where the popular ones are JSON and XML.

So, integration with such third parties through a simple and common API requires quite a lot of abstraction. Hopefully, Play! Framework 2 has prepared the field with an API sharing concepts used in controllers' actions, such as body parsers, for instance. So it won't take that much effort to understand how we can use it.

Actually, all that we'll need is a single endpoint for Java and another one for Scala:

  • In Java, the play.libs.WS class declares plenty of static methods dealing with web services
  • In Scala, there is the play.api.libs.ws.WS object, which contains the same functions as in Java, but with a Scala flavor

Indeed, these classes define all of the methods we'll need to interact efficiently with our HTTP services.

WS defines two important classes: WSRequestHolder and Response. WSRequestHolder enables multiple request creation and execution of all kinds (GET, POST, streams, files, and so on). Response is obviously the opposite, that is, it holds the result of our request after processing including the status, data, and so on.

But in fact, we'll never create any of them because Play! Framework 2 also abstracts their usage through the function url in WS. This function is able to create WSRequestHolder using the String argument we must pass in, which is the base URL. The following screenshot shows the skeleton of the WS class:

Accessing third parties

Ok, now what does WSRequestHolder stand for? In simple terms, it provides the abstraction over the creation of HTTP requests.

So, with such an instance of WSRequestHolder, we can prepare the query by setting some parameters using setQueryParameter, and give it some authentication information using setAuth (and so on for other preparation methods).

Having prepared the query, the resulting instance can be sent using methods such as get, put, post, delete, head, or option. The methods put and post are overloaded several times because they can be assigned with a body content; that's the purpose of methods such as put(InputStream body) or post(String body).

That was for the request part; let's see what's reserved for us by Play! Framework 2 on the response side. But, before moving to this part, we should take a look at the return type of the send methods (get, put, post, and so on):

Accessing third parties

In the previous screenshot, which presents one of the put methods available to send a body to a web service using the HTTP PUT method, we can see the Promise<Response> result type.

Promise is a structure that is nowadays more and more popular across languages because of its worth in the Web world. For instance, jQuery.Deferred is one good example a Promise object because of its heavy usage in the jQuery framework. In a way, it represents an AJAX call.

The main purpose of Promise is to create a task that will be processed at some time, asynchronously, that is, in a non-blocking way. Actually, it is built upon another concept called Future , which is the real asynchronous piece as its name intuitively implies. So, the put method is promising the invoker that a Response instance will be available. Hence, Play! is able to react in such a way that it will suspend this action once the result has arrived.

We can now get back to our Response type, which is the generic type of the Promise object we've just discussed—which declares that a sent request is promised to get some response at some point.

Accessing third parties

Great! Finally, a response is exactly the same as an action definition; it presents methods that are very similar to the ones we've seen up until now. Indeed, the highlighted methods are shortcuts that enable us to retrieve the response's body (remember, for actions it was the body of the request) that is parsed and represented as well-known and traversable structures such as XML, JSON, and so on.

The amazing hidden feature that is provided in Play! 2 is that the body is handled, parsed, and translated in a completely reactive fashion, thanks to the Iteratee pattern that is used, similar to what was done for the requests' body.

Now that we've got the overview of the API, we'll look at it in action. For that, we'll choose a third-party service and try to integrate it smoothly into our application.

Let's take Twitter as this third-party service. Twitter exposes an API on top of its social network which enables us to do almost everything that we would like to do with Twitter, such as tweeting a small message, recovering others based on a hashtag, or even searching for new users. Even though most of the functions provided by this service require an authentication, others aren't. As the implementation of such an authentication protocol (such as OAuth 2) is beyond the scope of this book, let's focus on the ones that don't require authentication.

Note

There is an amazing Play! add-on (plugin) that eases integration with external services, especially for social ones. Some information regarding the add-on can be found at http://securesocial.ws.

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

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