Book Image

RESTful Web Services with Scala

By : Jos Dirksen
Book Image

RESTful Web Services with Scala

By: Jos Dirksen

Overview of this book

<p>RESTful web services are built to work best on the web. Scala provides a rich set of language constructs and advanced frameworks that you can use to create REST services. However, using Scala and these tools can be a complex task. There are many frameworks available and choosing the wrong framework or approach can cost a lot of time and lead to much frustration. By exploring the most popular Scala REST frameworks, you can make sure you choose the right tool.</p> <p>RESTful Web Services with Scala begins with a brief explanation of the REST architecture and its implementation in Scala, as well as the impact that REST architecture has on Scala applications. You will understand the advantages of building Scala web services and how existing Scala applications can take advantage of REST. This book will teach developers about the different programming paradigms available in the Scala world to create RESTful services by exploring the most popular Scala-oriented REST frameworks. It discusses the various facets of RESTful web services such as building scalable APIs, working with standards like HTTP and MIME, designing the architecture, securing the web service, and more.</p> <p>With this book, you will be able to build RESTful web services with various Scala frameworks such as Finch, Unfiltered, Scalatra, Akka-HTTP, and Play. You will create basic REST services using frameworks and then extend the REST services with custom functionality. By the end of the book, you'll be able to decide which framework is best suited for your requirements. We finish by looking at how we can use a number of advanced features provided by these frameworks, such as security, creating HTTP clients, working with HATEOAS, and more.</p>
Table of Contents (14 chapters)
RESTful Web Services with Scala
Credits
About the Author
About the Reviewer
www.PacktPub.com
Preface
Index

Introduction to the REST framework


In this book, when we talk about REST, we talk about REST as described in the dissertation of Roy Fielding (https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm). Basically, REST is a software architecture style, which, when following the guidelines, can be used to create performant, reliable, and maintainable services. To better understand what REST is, it is a good idea to start with the constraints a service must follow to be RESTful. In his dissertation, Roy Fielding defines the following set of constraints:

  • Client-server: This constraint means that clients and servers are separated from each other through a standardized interface. The advantage of this approach is that clients don't need to worry about persistency, databases, messaging, scalability, and other server-side concepts; instead, they can focus on user-oriented functionality. Another advantage is that clients and servers can be developed independently since the only dependency between them is the standardized contract. Note that if you require a very strict contract between the client and the server, a WSDL/SOAP-based service might be a better option than going for a RESTful approach.

  • Stateless: Besides having a separate client and server, communication between these two components will have to be stateless. This means that each request the client sends should contain all the information necessary for the server. Note that for authentication, the server can temporarily store some session/user information in a persistent store, but all the real application state should be stored at the client. The big advantage of this approach is that this way it is very easy to scale out the servers horizontally by just adding more instances.

  • Cacheable: In a RESTful architecture, clients are allowed to cache responses. It is up to the server side to indicate which responses might be cached and for how long. The goal of this constraint is to minimize interactions between the client and the server by avoiding sending requests, whose response will stay the same. This, of course, improves performance at the client side and reduces bandwidth.

  • Layered system: This constraint describes that in a RESTful architecture, it is possible to create a layered system, where each layer has its own specific functionality. For instance, in between the client and the server, there might be a firewall, a load balancer, a reverse proxy, and so on. The client, however, doesn't notice these different layers.

  • Uniform interface: From all the constraints, this is perhaps the most interesting one. This constraint defines what a uniform interface (the contract between the client and the server) should look similar to. This constraint itself consists of the following four sections:

    • Identification of resources: In requests, each resource should be uniquely identified. Most often, this is done through a form of URI. Note that the technical representation of a resource doesn't matter. A resource, identified through a URI, can be represented in JSON, CSV, XML, and PDF while still remaining the same resource.

    • Manipulation of resources through these representations: When a client has a representation of a resource (for example, a JSON message), the client can modify this resource by updating the representation and sending it to the server.

    • Self-descriptive messages: Each message sent between the client and the server should be self-descriptive. The client need not know anything else to be able to parse and process the message. It should be able to learn from the message exactly what it can do with the resource.

    • Hypermedia as the engine of application state: This constraint, also called HATEOAS, implies that a user of an API doesn't need to know beforehand what it can do with a specific resource. Through the use of links in the resource and the definition of media-types, a client can explore and learn the actions it can take on a resource.

    • Code on demand: Code on demand is the only constraint that is optional. When comparing this constraint with the others, it is also one that is a bit different than the others. The idea behind this constraint is that servers could temporarily extend the functionality of clients by transferring executable code. In practice, this constraint is not seen that often though; most RESTful services deal with sending static responses, not executable code.

It's important to note that these constraints don't say anything about an implementation technology.

Tip

Often, when talking about REST, people immediately focus on HTTP and JSON. A RESTful architecture doesn't force you to adopt these technologies. On the other hand, most often, RESTful architectures are implemented on top of HTTP and currently use JSON as the message format. In this book, we will also focus on using HTTP and JSON to implement RESTful services.

The constraints mentioned here give an overview of how a service should act to be considered RESTful. However, when creating a service, it is often very hard to comply with all these constraints, and in some cases, not all the constraints might be that useful, or might be very hard to implement. Many people noticed this, and a couple of years ago, a more pragmatic view on REST was presented by Richardson's Maturity Model (http://martinfowler.com/articles/richardsonMaturityModel.html).

In Richardson's Maturity Model, you don't have to follow all the constraints to be considered RESTful; instead, a number of levels of maturity are defined that indicate how RESTful your service is. The higher the level, the more mature your service is, which will result in a more maintainable, more scalable, and easier-to-use service. This model defines the following levels:

The levels are described like this:

  • Level 0 describes the situation where you just send XML or JSON objects to a single HTTP endpoint. Basically, you're not doing REST, but you're doing RPC over HTTP.

  • Level 1 tackles the question of handling complexity by using divide and conquer, breaking a large service endpoint down into multiple resources

  • Level 2 introduces a standard set of verbs so that we can handle similar situations in the same way, removing unnecessary variation

  • Level 3 introduces discoverability, providing a way of making a protocol more self-documenting

In this book, we'll mostly focus on supporting REST at Level 2. So, we'll work with well-defined resources and use the appropriate HTTP verbs to indicate what we want to do with a resource.

In Chapter 7, JSON, HATEOAS, and Documentation, of this book, we'll address HATEOAS, which can help us reach maturity Level 3.

Now that we've got the theory out of the way, let's get the code, set up your favorite IDE, and define the API for the REST service we'll implement.