Sprint Rest

  • Uploaded by: Trưởng Phạm
  • Size: 4.8 MB
  • Type: PDF
  • Words: 47,023
  • Pages: 222
Report this file Bookmark

* The preview only shows a few pages of manuals at random. You can get the complete content by filling out the form below.

The preview is currently being created... Please pause for a moment!

Description

Spring REST Balaji Varanasi Sudha Belida

Spring REST Copyright © 2015 by Balaji Varanasi and Sudha Belida This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now known or hereafter developed. Exempted from this legal reservation are brief excerpts in connection with reviews or scholarly analysis or material supplied specifically for the purpose of being entered and executed on a computer system, for exclusive use by the purchaser of the work. Duplication of this publication or parts thereof is permitted only under the provisions of the Copyright Law of the Publisher’s location, in its current version, and permission for use must always be obtained from Springer. Permissions for use may be obtained through RightsLink at the Copyright Clearance Center. Violations are liable to prosecution under the respective Copyright Law. ISBN-13 (pbk): 978-1-4842-0824-3 ISBN-13 (electronic): 978-1-4842-0823-6 Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the trademark. The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to proprietary rights. While the advice and information in this book are believed to be true and accurate at the date of publication, neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or omissions that may be made. The publisher makes no warranty, express or implied, with respect to the material contained herein. Managing Director: Welmoed Spahr Lead Editor: Steve Anglin Technical Reviewer: Deepak Vohra Editorial Board: Steve Anglin, Louise Corrigan, Jonathan Gennick, Robert Hutchinson, Michelle Lowman, James Markham, Susan McDermott, Matthew Moodie, Jeffrey Pepper, Douglas Pundick, Ben Renow-Clarke, Gwenan Spearing, Steve Weiss Coordinating Editor: Mark Powers Copy Editor: Laura Lawrie Compositor: SPi Global Indexer: SPi Global Artist: SPi Global Distributed to the book trade worldwide by Springer Science+Business Media New York, 233 Spring Street, 6th Floor, New York, NY 10013. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail [email protected], or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc is a Delaware corporation. For information on translations, please e-mail [email protected], or visit www.apress.com. Apress and friends of ED books may be purchased in bulk for academic, corporate, or promotional use. eBook versions and licenses are also available for most titles. For more information, reference our Special Bulk Sales– eBook Licensing web page at www.apress.com/bulk-sales. Any source code or other supplementary material referenced by the author in this text is available to readers at www.apress.com/9781484208243. For detailed information about how to locate your book’s source code, go to www.apress.com/source-code/.

To Our Family

Contents at a Glance About the Authors About the Techincal reviewer Acknowledgments Introduction Chapter 1: Introduction to REST Chapter 2: Spring Web MVC Primer Chapter 3: RESTful Spring Chapter 4: Beginning QuickPoll Application Chapter 5: Error Handling Chapter 6: Documenting REST Services Chapter 7: Versioning, Paging, and Sorting Chapter 8: Security Chapter 9: Clients and Testing Chapter 10: HATEOAS Appendix A: Installing cURL on Windows Index

Contents About the Authors About the Techincal reviewer Acknowledgments Introduction Chapter 1: Introduction to REST What is REST? Understanding Resources Identifying Resources URI Templates

Representation HTTP Methods Safety Idempotency GET HEAD DELETE PUT POST PATCH

HTTP Status Codes Richardson’s Maturity Model Level Zero Level One Level Two Level Three

Building a RESTful API Summary Chapter 2: Spring Web MVC Primer Spring Overview Dependency Injection Aspect Oriented Programming

Spring Web MVC Overview Model View Controller Pattern Spring Web MVC Architecture Spring Web MVC Components

Summary Chapter 3: RESTful Spring Generating a Spring Boot Project Installing a Build Tool Generating a Project using start.spring.io Generating a Project using STS Generating a Project Using the CLI

Accessing REST Applications Postman RESTClient

Summary Chapter 4: Beginning QuickPoll Application Introducing QuickPoll Designing QuickPoll Resource Identification Resource Representation Endpoint Identification Action Identification

QuickPoll Architecture Implementing QuickPoll Domain Implementation Repository Implementation Embedded Database API Implementation

Summary Chapter 5: Error Handling QuickPoll Error Handling Error Responses Input Field Validation

Externalizing Error Messages Improving RestExceptionHandler Summary Chapter 6: Documenting REST Services Swagger Integrating Swagger Swagger UI Customizing Swagger Configuring Controllers Configuring UI Summary Chapter 7: Versioning, Paging, and Sorting Versioning Versioning Approaches Deprecating an API QuickPoll Versioning Swagger config

Pagination Page Number Pagination Limit Offset Pagination Cursor-Based Pagination Time-Based Pagination Pagination Data QuickPoll Pagination Changing Default Page Size

Sorting Sort Ascending or Sort Descending QuickPoll Sorting

Summary Chapter 8: Security Securing REST Services Session-based Security

HTTP Basic Authentication Digest Authentication Certificate-Based Security XAuth OAuth 2.0

Spring Security Overview Securing QuickPoll cURL User Infrastructure Setup UserDetailsService Implementation Customizing Spring Security Securing URI QuickPoll OAuth 2.0 Provider Implementation Testing QuickPoll OAuth 2.0 Implementation

Summary Chapter 9: Clients and Testing QuickPoll Java Client RestTemplate Getting Polls Creating a Poll PUT Method DELETE Method Handling Pagination Handling Basic Authentication Handling OAuth 2

Testing REST Services Spring Test Unit Testing REST Controllers Integration Testing REST Controllers

Summary Chapter 10: HATEOAS HATEOAS JSON Hypermedia Types JSON Hypermedia Types HAL

HATEOAS in QuickPoll Summary Appendix A: Installing cURL on Windows Index

About the Authors

Balaji Varanasi is a software development manager, author, speaker, and technology entrepreneur. He has over 14 years’ experience designing and developing highperformance, scalable Java and .NET mobile applications. He has worked in the areas of security, Web accessibility, search, and enterprise portals. He has a Master’s degree in computer science from Utah State University and serves as adjunct faculty at the University of Phoenix, teaching programming and information system courses. He has authored Apress’s Practical Spring LDAP and has coauthored Introducing Maven.

Sudha Belida is a senior software engineer and technology enthusiast. She has more than seven years’ experience working with Java and JEE technologies and frameworks such as Spring, Hibernate, Struts, and AngularJS. Her interests lie in entrepreneurship and agile methodologies for software design and development. She has a Master’s degree in computational science from the University of Utah. She has coauthored Apress’s Introducing Maven book.

About the Techincal reviewer

Deepak Vohra is a consultant and a principal member of the NuBean.com software company. Deepak is a Sun-certified Java programmer and Web component developer. He has worked in the fields of XML, Java programming, and Java EE for over five years. Deepak is the coauthor of Pro XML Development with Java Technology (Apress, 2006). Deepak is also the author of the JDBC 4.0 and Oracle JDeveloper for J2EE Development, Processing XML Documents with Oracle JDeveloper 11g, EJB 3.0 Database Persistence with Oracle Fusion Middleware 11g, and Java EE Development in Eclipse IDE (Packt Publishing). He also served as the technical reviewer on WebLogic: The Definitive Guide (O’Reilly Media, 2004) and Ruby Programming for the Absolute Beginner (Cengage Learning PTR, 2007).

Acknowledgments This book would not have been possible without the support of several people, and we would like to take this opportunity to sincerely thank them. Thanks to the amazing folks at Apress; without you, this book would not have seen the light of day. Thanks to Mark Powers for being patient and keeping us focused. Thanks to Matthew Moodie and Laura Lawrie for their suggestions in making this book better. Thanks to Steve Anglin for his constant support and the rest of the Apress team involved in this project. Huge thanks to our technical reviewer Deepak Vohra for his efforts and attention to detail. His valuable feedback has led to many improvements in the book. Finally, we would like to thank our friends and family for their constant support and encouragement.

Introduction Spring REST serves as a practical guide for designing and developing RESTful APIs using the popular Spring Framework. This book begins with a brief introduction to REST, HTTP, and Web infrastructure. It then provides detailed coverage of several Spring portfolio projects such as Spring Boot, Spring MVC, Spring Data JPA, and Spring Security. The book walks through the process of designing and building a REST application while taking a deeper look into design principles and best practices for versioning, security, documentation, error handling, paging, and sorting. It also discusses techniques for building clients that consume REST services. Finally, it covers Spring MVC test frameworks for creating unit and integration tests for REST API. After reading the book, you will have learned: About REST fundamentals and Web infrastructure About Spring technologies such as Spring Boot and Spring Data JPA How to build REST applications with Spring technologies How to identify REST resources and design their representations Design principles for versioning REST services How to document REST services using Swagger Strategies for handling errors and communicating meaningful messages Techniques for handling large datasets using pagination Securing REST services using “Basic Auth” and “OAuth 2.0” How to build REST clients using RestTemplate How to test REST services using the Spring MVC Test framework

How Is This Book Structured? Chapter 1 starts with an overview of REST. We cover REST fundamentals and abstractions such as resources and representations. We then discuss Web infrastructure such as URIs, HTTP methods, and HTTP response codes. We also cover Richardson’s Maturity Model, which provides a classification of REST services. Chapter 2 provides detailed coverage of Spring Web MVC. We begin with a gentle introduction to the Spring Framework and cover its two important concepts—Dependency Injection and Aspect Oriented Programming. Then we take a deeper look at the different components that make up Spring Web MVC. Chapter 3 introduces Spring Boot, a Spring project that simplifies the bootstrapping of Spring applications. We then use Spring Boot to build a Hello World REST application. Finally, we look at some tools that can be used to access REST applications.

Chapter 4 discusses the beginnings of a RESTful application named QuickPoll. We analyze the requirements and design resources and their representations. Using Spring MVC components, we implement a set of RESTful services. Chapter 5 covers error handling in REST services. Well-designed, meaningful error responses play an important role in the adoption of REST services. We design a custom error response for QuickPoll and implement the design. We also add validation capabilities to the inputs provided by users. Finally, we look at techniques for externalizing the error messages to property files. Chapter 6 begins with an overview of the Swagger specification and its associated tools/frameworks. We then implement Swagger in QuickPoll to generate interactive documentation. We also customize Swagger and Swagger UI to meet our application requirements. Chapter 7 covers the different strategies for versioning a REST API. We then look at implementing versioning in QuickPoll using the URI versioning approach. We also review the different approaches for dealing with large datasets using pagination and sorting. Chapter 8 begins with a discussion of different strategies for securing REST services. We provide a detailed treatment of OAuth 2 and review its different components. We then use the Spring Security framework to implement Basic Authentication and OAuth 2 in the QuickPoll application. Chapter 9 covers building REST clients and testing REST APIs. We use Spring’s RestTemplate features to build a REST client that works with different versions of the QuickPoll API. We then take a deeper look into the Spring MVC Test framework and examine its core classes. Finally, we write unit and integration tests to test the REST API. Chapter 10 discusses the HATEOAS constraint that allows developers build flexible and loosely coupled REST services. It also covers the HAL hypermedia format. We then modify the QuickPoll application such that the Poll representations are generated following HATEOAS principles. Appendix A provides step-by-step instructions for downloading and installing cURL on a Windows machine. Chapter 8 makes use of cURL for testing REST services.

Target Audience Spring REST is intended for enterprise and Web developers using Java and Spring who want to build REST applications. The book requires a basic knowledge of Java, Spring, and the Web but no prior exposure to REST.

Downloading the Source Code The source code for the examples in this book can be downloaded from www.apress.com. Detailed information regarding the source code with examples for this book can be downloaded from www.apress.com/9781484208243. The source

code is also available on GitHub at https://github.com/bava/springrestbook. The downloaded source code contains a number of folders named ChapterX, in which X represents the corresponding chapter number. Each ChapterX folder contains two subfolders: a starter folder and a final folder. The starter folder houses a QuickPoll project that you can use as a basis to follow along the solution described in the corresponding chapter. Even though each chapter builds on the previous one, the starter project allows you to skip around the book. For example, if you are interested in learning about security, you can simply load the QuickPoll application under the Chapter8\starter folder and follow the solution described in Chapter 8. As the name suggests, the final folder contains the expected end state for that chapter. Chapters 1 and 2 don’t have any associated code. Therefore, the corresponding ChapterX folders for those chapters contain empty starter and final folders. In Chapter 3, we build a Hello World application, so Chapter3’s starter and final folders contain the hello-rest application. Starting from Chapter 4, the starter and final folders contain QuickPoll project source code.

Contacting the Authors We always welcome feedback from our readers. If you have any questions or suggestions regarding the contents of this book, you can contact the authors at [email protected] or [email protected].

CHAPTER 1

Introduction to REST In this chapter, we will learn: REST fundamentals REST resources and their representations HTTP methods and status codes Richardson’s maturity model Today, the Web has become an integral part of our lives—checking statuses on Facebook to ordering products online to communicating via email. The success and ubiquity of the Web has resulted in organizations applying the Web’s architectural principles to building distributed applications. In this chapter, we will take a deep dive into REST, an architectural style that formalizes these principles.

What is REST? REST stands for REpresentational State Transfer and is an architectural style for designing distributed network applications. Roy Fielding coined the term REST in his PhD dissertation1 and proposed the following six constraints or principles as its basis: Client-Server—Concerns should be separated between clients and servers. This enables client and server components to evolve independently and in turn allows the system to scale. Stateless—The communication between client and server should be stateless. The server need not remember the state of the client. Instead, clients must include all of the necessary information in the request so that server can understand and process it. Layered System—Multiple hierarchical layers such as gateways, firewalls, and proxies can exist between client and server. Layers can be added, modified, reordered, or removed transparently to improve scalability. Cache—Responses from the server must be declared as cacheable or noncacheable. This would allow the client or its intermediary components to cache responses and reuse them for later requests. This reduces the load on the server and helps improve the performance. Uniform Interface— All interactions between client, server, and

trung gian

intermediary components are based on the uniformity of their interfaces. This simplifies the overall architecture as components can evolve independently as long as they implement the agreed-on contract. The uniform interface constraint is further broken down into four subconstraints—resource identification, resource representations, self-descriptive messages, and hypermedia as the engine of application state or HATEOAS. We will examine some of these guiding principles in the later sections of this chapter. Code on demand—Clients can extend their functionality by downloading and executing code on demand. Examples include JavaScript scripts, Java applets, Silverlight, and so on. This is an optional constraint. Applications that adhere to these constraints are considered to be RESTful. As you might have noticed, these constraints don’t dictate the actual technology to be used for developing applications. Instead, adherence to these guidelines and best practices would make an application scalable, visible, portable, reliable, and able to perform better. In theory, it is possible for a RESTful application to be built using any networking infrastructure or transport protocol. In practice, RESTful applications leverage features and capabilities of the Web and use HTTP as the transport protocol. The Uniform Interface constraint is a key feature that distinguishes REST applications from other network-based applications. Uniform Interface in a REST application is achieved through abstractions such as resources, representations, URIs, and HTTP methods. In the next sections, we will look at these important REST abstractions.

Understanding Resources “The key abstraction of information in REST is a resource.” —Roy Fielding Fundamental to REST is the concept of resource. A resource is anything that can be accessed or manipulated. Examples of resources include “videos,” “blog entries,” “user profiles,” “images,” and even tangible things such as persons or devices. Resources are typically related to other resources. For example, in an ecommerce application, a customer can place an order for any number of products. In this scenario, the product resources are related to the corresponding order resource. It is also possible for a resource to be grouped into collections. Using the same ecommerce example, “orders” is a collection of individual “order” resources.

Identifying Resources Before we can interact and use a resource, we must be able to identify it. The Web provides the Uniform Resource Identifier, or URI, for uniquely identifying resources. The syntax of a URI is:

scheme:scheme-specific-part The scheme and the scheme-specific-part are separated using a semicolon. Examples of a scheme include http or ftp or mailto and are used to define the semantics and interpretation of the rest of the URI. Take the example of the URI —http://www.apress.com/9781484208427. The http portion of the example is the scheme; it indicates that a HTTP scheme should be used for interpreting the rest of the URI. The HTTP scheme, defined as part of RFC 7230,2 indicates that the resource identified by our example URI is located on a machine with host name apress.com. Table 1-1 shows examples of URIs and the different resources they represent. Table 1-1. URI and resource description URI

Resource Description

http://blog.example.com/posts

Represents a collection of blog post resources

http://blog.example.com/posts/1

Represents a blog post resource with identifier “1”; such resources are called singleton resources

http://blog.example.com/posts/1/comments

Represents a collection of comments associated with the blog entry identified by “1”; collections such as these that reside under a resource are referred to as subcollections

http://blog.example.com/posts/1/comments/245

Represents the comment resource identified by “245”

Even though a URI uniquely identifies a resource, it is possible for a resource to have more than one URI. For example, Facebook can be accessed using URIs https://www.facebook.com and https://www.fb.com. The term URI aliases is used to refer to such URIs that identify the same resources. URI aliases provide flexibility and added convenience such as having to type fewer characters to get to the resource.

URI Templates When working with REST and a REST API, there will be times where you need to represent the structure of a URI rather than the URI itself. For example, in a blog application, the URI http://blog.example.com/2014/posts would retrieve all the blog posts created in the year 2014. Similarly, the URIs http://blog.example.com/2013/posts, http://blog.example.com/2012/posts, and so forth would return blog posts corresponding to the years 2013, 2012, and so on. In this scenario, it would be convenient for a consuming client to know the URI structure http://blog.example.com/year/posts that describes the range of URIs rather

than individual URIs. URI templates, defined in RFC 6570 (http://tools.ietf.org/html/rfc6570), provide a standardized mechanism for describing URI structure. The standardized URI template for this scenario could be: http://blog.example.com/{year}/posts The curly braces {} indicate that the year portion of the template is a variable, often referred to as a path variable. Consuming clients can take this URI template as input, substitute the year variable with the right value, and retrieve the corresponding year’s blog posts. On the server side, URL templates allow the server code to parse and retrieve the values of the variables or selected portions of URI easily.

Representation RESTful resources are abstract entities. The data and metadata that make a RESTful resource needs to be serialized into a representation before it gets sent to a client. This representation can be viewed as a snapshot of a resource’s state at a given point in time. Consider a database table in an ecommerce application that stores information about all the available products. When an online shopper uses their browser to buy a product and requests its details, the application would provide the product details as a Web page in HTML. Now, when a developer writing a native mobile application requests product details, the ecommerce application might return those details in XML or JSON format. In both scenarios, the clients didn’t interact with the actual resource—the database recordholding product details. Instead, they dealt with its representation. Note REST components interact with a resource by transferring its representations back and forth. They never directly interact with the resource. As noted in this product example, the same resource can have several representations. These representations can range from text-based HTML, XML, and JSON formats to binary formats such as PDFs, JPEGs, and MP4s. It is possible for the client to request a particular representation and this process is termed as content negotiation. Here are the two possible content negotiation strategies: Postfixing the URI with the desired representation—In this strategy, a client requesting product details in JSON format would use the URI http://www.example.com/products/143.json. A different client might use the URI http://www.example.com/products/143.xml to get product details in XML format. Using the Accept header—Clients can populate the HTTP Accept header with the desired representation and send it along with the request. The application handling the resource would use the Accept

header value to serialize the requested representation. The RFC 26163 provides a detailed set of rules for specifying one or more formats and their priorities. Note JSON has become the de facto standard for REST services. All of the examples in this book use JSON as the data format for requests and responses.

HTTP Methods The “Uniform Interface” constraint restricts the interactions between client and server through a handful of standardized operations or verbs. On the Web, the HTTP standard4 provides eight HTTP methods that allow clients to interact and manipulate resources. Some of the commonly used methods are GET, POST, PUT, and DELETE. Before we delve deep in to HTTP methods, let’s review their two important characteristics—safety and idempotency. Note The HTTP specification uses the term method to denote HTTP actions such as GET, PUT, and POST. However, the term HTTP verb is also used interchangeably.

Safety A HTTP method is said to be safe if it doesn’t cause any changes to the server state. Consider methods such as GET or HEAD, which are used to retrieve information/resources from the server. These requests are typically implemented as readonly operations without causing any changes to the server’s state and, hence, considered safe. Safe methods are used to retrieve resources. However, safety doesn’t mean that the method must return the same value every time. For example, a GET request to retrieve Google stock might result in a different value for each call. But as long as it didn’t alter any state, it is still considered safe. In real-world implementations, there may still be side effects with a safe operation. Consider the implementation in which each request for stock prices gets logged in a database. From a purist perspective we are changing the state of the entire system. However, from a practical standpoint, because these side effects were the sole responsibility of the server implementation, the operation is still considered to be safe.

Idempotency An operation is considered to be idempotent if it produces the same server state whether we apply it once or any number of times. HTTP methods such as GET, HEAD (which are also safe), PUT, and DELETE are considered to be idempotent, guaranteeing that clients can repeat a request and expect the same effect as making the request once. The second

and subsequent requests leave the resource state in exactly the same state as the first request did. Consider the scenario in which you are deleting an order in an ecommerce application. On successful completion of the request, the order no longer exists on the server. Hence, any future requests to delete that order would still result in the same server state. By contrast, consider the scenario in which you are creating an order using a POST request. On successful completion of the request, a new order gets created. If you were to re“POST” the same request, the server simply honors the request and creates a new order. Because a repeated POST request can result in unforeseen side effects, POST is not considered to be idempotent.

GET The GET method is used to retrieve a resource’s representation. For example, a GET on the URI http://blog.example.com/posts/1 returns the representation of the blog post identified by 1. By contrast, a GET on the URI http://blog.example.com/posts retrieves a collection of blog posts. Because GET requests don’t modify server state, they are considered to be safe and idempotent. A hypothetical GET request to http://blog.example.com/posts/1 and the corresponding response are shown here. GET /posts/1 HTTP/1.1

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/ Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.5 Connection: keep-alive Host: blog.example.com Content-Type: text/html; charset=UTF-8

Date: Sat, 10 Jan 2015 20:16:58 GMT Server: Apache First Post

Hello World!!

In addition to the representation, the response to GET requests includes metadata associated with the resource. This metadata is represented as a sequence of key value pairs

called HTTP headers. Content-Type and Server are examples of the headers that you see in this response. Because the GET method is safe, responses to GET requests can be cached. lạm dụng

The simplicity of the GET method is often abused and it is used to perform operations such as deleting or updating a resource’s representation. Such usage violates standard vi phạm, cưỡng hiếp HTTP semantics and is highly discouraged. Ngữ nghĩa

HEAD On occasions, a client would like to check if a particular resource exists and doesn’t really care about the actual representation. In another scenario, the client would like to know if a newer version of the resource is available before it downloads it. In both cases, a GET request could be “heavyweight” in terms of bandwidth and resources. Instead, a HEAD method is more appropriate.Thich hop The HEAD method allows a client to only retrieve the metadata associated with a resource. No resource representation gets sent to the client. This metadata represented as HTTP headers will be identical to the information sent in response to a GET request. The client uses this metadata to determine resource accessibility and recent modifications. Here is a hypothetical HEAD request and the response. HEAD /posts/1 HTTP/1.1

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/ Accept-Encoding: gzip, deflate Accept-Language: en-US,en;q=0.5 Connection: keep-alive Host: blog.example.com Connection: Keep-Alive

Content-Type: text/html; charset=UTF-8 Date: Sat, 10 Jan 2015 20:16:58 GMT Server: Apache Like GET, the HEAD method is also safe and idempotent and responses can be cached on the client.

DELETE The DELETE method, as the name suggests, requests a resource to be deleted. On receiving the request, a server deletes the resource. For resources that might take a long time to delete, the server typically sends a confirmation that it has received the request and will work on it. Depending on the service implementation, the resource may or may not be physically deleted. On successful deletion, future GET requests on that resource would yield a “Resource Not Found” error via HTTP status code 404. We will be covering status codes in just a

minute. In this example, the client requests a post identified by 1 to be deleted. On completion, the server could return a status code 200 (OK) or 204 (No Content), indicating that the request was successfully processed. Delete /posts/1 HTTP/1.1

Content-Length: 0 Content-Type: application/json Host: blog.example.com Similarly, in this example, all comments associated with post #2 get deleted. Delete /posts/2/comments HTTP/1.1

Content-Length: 0 Content-Type: application/json Host: blog.example.com Because DELETE method modifies the state of the system, it is not considered to be safe. However, the DELETE method is considered idempotent; subsequent DELETE requests would still leave the resource and the system in the same state.

PUT The PUT method allows a client to modify a resource state. A client modifies the state of a resource and sends the updated representation to the server using a PUT method. On receiving the request, the server replaces the resource’s state with the new state. In this example, we are sending a PUT request to update a post identified by 1. The request contains an updated blog post’s body along with all of the other fields that make up the blog post. The server, on successful processing, would return a status code 200, indicating that the request was processed successfully. PUT /posts/1 HTTP/1.1

Accept: */* Content-Type: application/json Content-Length: 65 Host: blog.example.com BODY {"title": "First Post","body": "Updated Hello World!!"} Consider the case in which we just wanted to update the blog post title. The HTTP semantics dictate that as part of the PUT request we send the full resource representation, which includes the updated title as well as other attributes such as blog post body and so on that didn’t change. However, this approach would require that the client has the complete resource representation, which might not be possible if the resource is very big or has a lot of relationships. Additionally, this would require higher bandwidth for data

transfers. So, for practical reasons, it is acceptable to design your API that tends to accept partial representations as part of a PUT request. Note To support partial updates, a new method called PATCH has been added as part of RFC 5789 (http://www.ietf.org/rfc/rfc5789.txt). We will be looking at the PATCH method later in this chapter. Clients can also use PUT method to create a new resource. However, it will only be possible when the client knows the URI of the new resource. In a blogging application, for example, a client can upload an image associated with a blog post. In that scenario, the client decides the URL for the image as shown in this example: PUT http://blog.example.com/posts/1/images/author.jpg PUT is not a safe operation, as it changes the system state. However, it is considered idempotent, as putting the same resource once or more than once would produce the same Sản xuất, tạo ra result.

POST The POST method is used to create resources. Typically, it is used to create resources under subcollections—resource collections that exist under a parent resource. For example, the POST method can be used to create a new blog entry in a blogging application. Here, “posts” is a subcollection of blog post resources that reside under a blog parent resource. POST /posts HTTP/1.1

Accept: */* Content-Type: application/json Content-Length: 63 Host: blog.example.com BODY {"title": "Second Post","body": "Another Blog Post."} Content-Type: application/json

Location: posts/12345 Server: Apache Unlike PUT, a POST request doesn’t need to know the URI of the resource. The server is responsible for assigning an ID to the resource and deciding the URI where the resource is going to reside. In the previous example, the blogging application will process the POST request and create a new resource under http://blog.example.com/posts/12345, where “12345” is the server generated id. The Location header in the response contains the URL of the newly

created resource. The POST method is very flexible and is often used when no other HTTP method seems appropriate. Consider the scenario in which you would like to generate a thumbnail for a JPEG or PNG image. Here we ask the server to perform an action on the image binary data that we are submitting. HTTP methods such as GET and PUT don’t really fit here, as we are dealing with an RPC-style operation. Such scenarios are handled using the POST method. Note The term “controller resource” has been used to describe executable resources that take inputs, perform some action, and return outputs. Although these types of resources don’t fit the true REST resource definition, they are very convenient to expose complex operations. The POST method is not considered safe, as it changes system state. Also, multiple POST invocations would result in multiple resources being generated, making it nonidempotent.

PATCH As we discussed earlier, the HTTP specification requires the client to send the entire resource representation as part of a PUT request. The PATCH method proposed as part of RFC 5789 (http://tools.ietf.org/html/rfc5789) is used to perform partial resource updates. It is neither safe nor idempotent. Here is an example that uses PATCH method to update a blog post title. PATCH /posts/1 HTTP/1.1

Accept: */* Content-Type: application/json Content-Length: 59 Host: blog.example.com BODY {"replace": "title","value": "New Awesome title"} The request body contains a description of changes that need to be performed on the resource. In the example, the request body uses the “replace” command to indicate that the value of the “title” field needs to be replaced. There is no standardized format for describing the changes to the server as part of a PATCH request. A different implementation might use the following format to describe the same change: {"change" : "name", "from" : "Post Title", "to" : "New Awesome Title"} Currently, there is a work in progress

(http://tools.ietf.org/html/draft-ietf-appsawg-json-patch) for defining a PATCH format for JSON. This lack of standard has resulted in implementations that describe change sets in a simpler format, as shown here: {"name" : "New Awesome Title"}

CRUD AND HTTP VERBS Data-driven applications typically use the term CRUD to indicate four basic persistence functions—Create, Read, Update, and Delete. Some developers building REST applications have mistakenly associated the four popular HTTP verbs GET, POST, PUT, and DELETE with CRUD semantics. The typical association often seen is: Create -> POST Update -> PUT Read -> GET Delete -> DELETE mối tương quan

These correlations are true for Read and Delete operations. However, it is not as straightforward for Create/Update and POST/PUT. As you have seen earlier in this chapter, PUT can be used to create a resource as long as idempotency constraint is met. In the same way it was never considered non-RESTful if POST is used for update (http://roy.gbiv.com/untangled/2009/it-is-okay-touse-post). It is also possible for a client to use PATCH for updating a resource. Therefore, it is important for API designers to use the right verbs for a given operation than simply using a 1-1 mapping with CRUD.

HTTP Status Codes The HTTP Status codes allow a server to communicate the results of processing a client’s request. These status codes are grouped into the following categories: Informational Codes—Status codes indicating that the server has received the request but hasn’t completed processing it. These intermediate response codes are in the 100 series. Success Codes—Status codes indicating that the request has been successfully received and processed. These codes are in the 200 series. Redirection Codes—Status codes indicating that the request has been processed, but the client must perform an additional action to complete the request. These actions typically involve redirecting to a different location to get the resource. These codes are in the 300 series. Client Error Codes—Status codes indicating that there was an error or a problem with client’s request. These codes are in the 400 series.

Server Error Codes—Status codes indicating that there was an error on the server while processing the client’s request. These codes are in the 500 series. The HTTP Status codes play an important role in REST API design as meaningful codes help communicate the right status, enabling the client to react appropriately. Table 1-2 shows some of the important status codes into which you typically run. Table 1-2. HTTP status codes and their descriptions Status Code

Description

100 (Continue)

Indicates that the server has received the first part of the request and the rest of the request should be sent.

200 (OK)

Indicates that all went well with the request.

201 (Created)

Indicates that request was completed and a new resource got created.

202 (Accepted)

Indicates that request has been accepted but is still being processed.

204 (No Content)

Indicates that the server has completed the request and has no entity body to send to the client.

301 (Moved Permanently)

Indicates that the requested resource has been moved to a new location and a new URI needs to be used to access the resource.

400 (Bad Request)

Indicates that the request is malformed and the server is not able to understand the request.

401 (Unauthorized)

Indicates that the client needs to authenticate before accessing the resource. If the request already contains client’s credentials, then a 401 indicates invalid credentials (e.g., bad password).

403 (Forbidden)

Indicates that the server understood the request but is refusing to fulfill it. This could be because the resource is being accessed from a blacklisted IP address or outside the approved time window.

404 (Not Found)

Indicates that the resource at the requested URI doesn’t exist.

406 (Not Acceptable)

Indicates that the server is capable of processing the request; however, the generated response may not be acceptable to the client. This happens when the client becomes too picky with its accept headers.

500 (Internal Server Error)

Indicates that there was an error on the server while processing the request and that the request can’t be completed.

503 (Service Unavailable)

Indicates that the request can’t be completed, as the server is overloaded or going through scheduled maintenance.

Richardson’s Maturity Model The Richardson’s Maturity Model (RMM), developed by Leonard Richardson, classifies

REST-based Web services on how well they adhere to REST principles. Figure 1-1 shows the four levels of this classification.

Figure 1-1. RMM levels

RMM can be valuable in understanding the different styles of Web service, their designs, benefits, and tradeoffs.

Level Zero This is the most rudimentary maturity level for a service. Services in this level use HTTP as the transport mechanism and perform remote procedure calls on a single URI. Typically, POST or GET HTTP methods are employed for service calls. SOAP- and XMLRPC-based Web services fall under this level.

Level One The next level adheres to the REST principles more closely and introduces multiple URIs, one per resource. Complex functionality of a large service endpoint is broken down into multiple resources. However, services in this layer use one HTTP verb, typically POST, to perform all of the operations.

Level Two Services in this level leverage HTTP protocol and make the right use of HTTP verbs and status codes available in the protocol. Web services implementing CRUD operations are good examples of Level 2 services.

Level Three This is the most mature level for a service and is built around the notion of Hypermedia as the Engine of Application State, or HATEOAS. Services in this level allow discoverability by providing responses that contain links to other related resources and controls that tell the client what to do next.

Building a RESTful API Designing and implementing a beautiful RESTful API is no less than an art. It takes time, effort, and several iterations. A well-designed RESTful API allows your end users to consume the API easily and makes its adoption easier. At a high level, here are the steps involved in building a RESTful API: 1. Identify Resources—Central to REST are resources. We start modeling different resources that are of interest to our consumers. Often, these resources can be the application’s domain or entities. However, a one-to-one mapping is not always required. 2. Identify Endpoints—The next step is to design URIs that map resources to endpoints. In Chapter 4, we will look at best practices for designing and naming endpoints. 3. Identify Actions—Identify the HTTP methods that can be used to perform operations on the resources. 4. Identify Responses—Identify the supported resource representation for the request and response along with the right status codes to be returned. In the rest of the book, we will look at best practices for designing a RESTful API and implementing it using Spring technologies.

Summary REST has become the de facto standard for building services today. In this chapter, we covered the fundamentals of REST and abstractions such as resources, representations, URIs, and HTTP methods that make up REST’s Uniform Interface. We also looked at RMM, which provides a classification of REST services. In the next chapter, we will take a deep dive into Spring and its related technologies that simplify REST service development. _____________________ 1https://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm. 2http://tools.ietf.org/html/rfc7230.

3http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1. 4https://www.ietf.org/rfc/rfc2616.txt.

CHAPTER 2 Võ lòng

Spring Web MVC Primer In this chapter, we will discuss: Spring and its features The Model View Controller Pattern Spring Web MVC and its components The Java ecosystem is filled with frameworks such as Jersey and RestEasy, which allow you to develop REST applications. Spring Web MVC is one such popular web framework that simplifies Web and REST application development. We begin this chapter with an overview of the Spring framework and take a deep dive into Spring Web MVC and its components. Bao quát, toàn diện

Note This book doesn’t give a comprehensive overview of Spring and Spring Web MVC. Refer to Pro Spring and Pro Spring MVC and WebFlow (both published by Apress) for detailed treatment of these concepts.

Spring Overview The Spring Framework has become the de facto standard for building Java/Java EE–based enterprise applications. Originally written by Rod Johnson in 2002, the Spring Framework is one of the suite of projects owned and maintained by Pivotal Software Inc. (http://spring.io). Among many other things, the Spring Framework provides a Sự rối rắm, lằng nhằng dependency injection model1 that reduces plumbing code for application development, supports aspect oriented programming (AOP) for implementing crosscutting concerns, and makes it easy to integrate with other frameworks and technologies. The Spring Framework is made up of different modules that offer services such as data access, instrumentation, messaging, testing, and Web integration. The different Spring Framework modules and their groupings are shown in Figure 2-1.

Figure 2-1. Spring Framework modules

As a developer, you are not forced to use everything that the Spring Framework has to offer. The modularity of the Spring Framework allows you to pick and choose the modules based on your application needs. In this book, we will be focusing on the Web module for developing REST services. Additionally, we will be using a few other Spring portfolio projects such as Spring Data, Spring Security, and Spring Boot. These projects are built on top of the infrastructure provided by the Spring Framework modules and are intended to simplify data access, authentication/authorization, and Spring application creation. Developing Spring-based applications requires a thorough understanding of two core concepts—Dependency Injection and Aspect Oriented Programming.

Dependency Injection At the heart of the Spring Framework lies Dependency Injection (DI). As the name suggests, Dependency Injection allows dependencies to be injected into components that need them. This relieves those components from having to create or locate their dependencies, allowing them to be loosely coupled. To better understand DI, consider the scenario of purchasing a product in an online retail store. Completing a purchase is typically implemented using a component such as an OrderService. The OrderService itself would interact with an OrderRepository that would create order details in a database and a NotificationComponent that would send out the order confirmation to the customer. In a traditional implementation, the OrderService creates (typically in its constructor) instances of OrderRepository and NotificationComponent and uses them. Even though there is nothing wrong with this bán lẻ

approach, it can lead to hard-to-maintain, hard-to-test, and highly coupled code. DI, by contrast, allows us to take a different approach when dealing with dependencies. With DI, you let an external process such as Spring create dependencies, manage dependencies, and inject those dependencies into the objects that need them. So, with DI, Spring would create the OrderRepository and NotificationComponent and then hand over those dependencies to the OrderService. This decouples OrderService from having to deal with OrderRepository/NotificationComponent creation, making it easier to test. It allows each component to evolve independently, making development and maintenance easier. Also, it makes it easier to swap these dependencies with different implementations or use these components in a different context.

Aspect Oriented Programming Aspect Oriented Programming (AOP) is a programming model that implements crosscutting logic or concerns. Logging, transactions, metrics, and security are some examples of concerns that span (crosscut) different parts of an application. These concerns don't deal with business logic and are often duplicated across the application. AOP provides a standardized mechanism called an aspect for encapsulating such concerns in a single location. The aspects are then weaved into other objects so that the crosscutting logic is automatically applied across the entire application. Spring provides a pure Java-based AOP implementation through its Spring AOP module. Spring AOP does not require any special compilation nor changes to the class loader hierarchy. Instead, Spring AOP uses proxies for weaving aspects into Spring beans at runtime. Figure 2-2 provides a representation of this behavior. When a method on the target bean gets called, the proxy intercepts the call. It then applies the aspect logic and invokes the target bean method.

Figure 2-2. Spring AOP Proxy

Spring provides two-proxy implementations—JDK dynamic proxy and CGLIB proxy. If the target bean implements an interface, Spring will use JDK dynamic proxy to create the AOP proxy. If the class doesn't implement an interface, Spring uses CGLIB to create a proxy.

Spring Web MVC Overview Spring Web MVC, part of the Spring Framework’s Web module, is a popular technology for building Web-based applications. It is based on the model-view-controller architecture and provides a rich set of annotations and components. Over the years, the framework has evolved; it currently provides a rich set of configuration annotations and features such as

flexible view resolution and powerful data binding.

Model View Controller Pattern The Model View Controller, or MVC, is an architectural pattern for building decoupled Web applications. This pattern decomposes the UI layer into the following three components: Model—The model represents data or state. In a Web-based banking application, information representing accounts, transactions, and statements are examples of the model. View—Provides a visual representation of the model. This is what the user interacts with by providing inputs and viewing the output. In our banking application, Web pages showing accounts and transactions are examples of views. Controller—The controller is responsible for handling user actions such as button clicks. It then interacts with services or repositories to prepare the model and hands the prepared model over to an appropriate view. Each component has specific responsibility. The interaction between them is shown in Figure 2-3. The interaction begins with the Controller preparing the model and selecting an appropriate view to be rendered. The View uses the data from the model for rendering. Further interactions with the View are sent to the Controller, which starts the process all over again.

Figure 2-3. Model View Controller interaction

Spring Web MVC Architecture

Spring’s Web MVC implementation revolves around the DispatcherServlet—an implementation of the FrontController Pattern2 that acts as an entry point for handling requests. Spring Web MVC’s architecture is shown in Figure 2-4.

Figure 2-4. Spring Web MVC's architecture

The different components in Figure 2-4 and their interactions include: 1. The interaction begins with the DispatcherServlet receiving the request from the client. 2. DispatcherServlet queries one or more HandlerMapping to figure out a Handler that can service the request. A Handler is a generic way of addressing a Controller and other HTTP-based endpoints that Spring Web MVC supports. 3. The HandlerMapping component uses the request path to determine the right Handler and passes it to the DispatcherServlet. The HandlerMapping also determines a list of Interceptors that need to get executed before (Pre-) and after (Post-) Handler execution. 4. The DispatcherServlet then executes the Pre-Process Interceptors if any are appropriate and passes the control to the Handler. 5. The Handler interacts with any Service(s) needed and prepares the model. 6. The Handler also determines the name of the view that needs to get rendered in the output and sends it to DispatcherServlet. The PostProcess Interceptors then get executed. 7. This is followed by the DispatcherServlet passing the logical View

name to a ViewResolver, which determines and passes the actual View implementation. 8. The DispatcherServlet then passes the control and model to the View, which generates response. This ViewResolver and View abstraction allows the DispatcherServlet to be decoupled from a particular View implementation. 9. The DispatcherServlet returns the generated response over to the client.

Spring Web MVC Components In the previous section, you were introduced to Spring Web MVC components such as HandlerMapping and ViewResolver. In this section, we will take a deeper look at those as well as additional Spring Web MVC components. Note In this book we will be using Java Configuration for creating Spring beans. Contrary to XML-based configuration, Java configuration provides compile time safety, flexibility, and added power/control.

Controller Controllers in Spring Web MVC are declared using the stereotype org.springframework.stereotype.Controller. A stereotype in Spring designates roles or responsibilities of a class or an interface. Listing 2-1 shows a basic controller. Listing 2-1. HomeController implementation @Controller public class HomeController { @RequestMapping("/home.html") public String showHomePage() { return "home"; } } The @Controller annotation designates the HomeController class as a MVC controller. The @RequestMapping annotation maps Web requests to handler classes and handler methods. In this case, the @RequestMapping indicates that when a request for home.html is made, the showHomePage method should get executed. The showHomePage method has a tiny implementation and simply returns the logical view name home. This controller did not prepare any model in this example.

Model

Spring provides the org.springframework.ui.Model interface that serves as holder for model attributes. Listing 2-2 shows the Model interface with the available methods. As the names suggest, the addAttribute and addAttributes methods can be used to add attributes to the model object. Listing 2-2. Model interface public interface Model { Model addAttribute(String attributeName, Object

attributeValue); Model addAttribute(Object attributeValue); Model addAllAttributes(Collection attributeValues); Model addAllAttributes(Map attributes); Model mergeAttributes(Map attributes); boolean containsAttribute(String attributeName); Map asMap();

} The easiest way for a controller to work with a model object is by declaring it as a method parameter. Listing 2-3 shows the showHomePage method with the Model parameter. In the method implementation, we are adding the currentDate attribute to the model object. Listing 2-3. showHomePage with Model attribute @RequestMapping("/home.html") public String showHomePage(Model model) { model.addAttribute("currentDate", new Date()); return "home"; } The Spring Framework strives to decouple our applications from the framework’s classes. So, a popular approach for working with model objects is to use a java.util.Map instance as shown in Listing 2-4. Spring would use the passed in Map parameter instance to enrich the model that gets exposed to the view. Listing 2-4. showHomePage with Map attribute @RequestMapping("/home.html") public String showHomePage(Map model) { model.put("currentDate", new Date()); return "home"; }

View Spring Web MVC supports a variety of view technologies such as JSP, Velocity, Freemarker, and XSLT. Spring Web MVC uses the org.springframework.web.servlet.View interface to accomplish this. The View interface has two methods, as shown in Listing 2-5. Listing 2-5. View Interface API public interface View { String getContentType(); void render(Map model, HttpServletRequest

request, HttpServletResponse response) throws Exception; } Concrete implementations of the View interface are responsible for rendering the response. This is accomplished by overriding the render method. The getContentType method returns the generated view's content type. Table 2-1 shows important View implementations that Spring Web MVC provides out of the box. You will notice that all of these implementations reside inside the org.springframework.web.servlet.view package. Table 2-1. Spring Web MVC View Implementations Class Name

Description

org.springframework.web.servlet.view.json. MappingJackson2JsonView

View implementation that encodes model attributes and returns JSON.

org.springframework.web.servlet.view.xslt.XsltView

View implementation that performs XSLT transformation and returns the response.

org.springframework.web.servlet.view. InternalResourceView

View implementation that delegates the request to a JSP page inside the web application.

org.springframework.web.servlet.view.tiles2.TilesView

View implementation that uses Apache Tiles configuration for Tile definition and rendering.

org.springframework.web.servlet.view.JstlView

Specialized implementation of InternalResourceView that supports JSP pages using JSTL. View implementation that

org.springframework.web.servlet.view.RedirectView

redirects to a different (absolute or relative) URL.

Listing 2-6 shows the reimplementation of the HomeController that we looked at earlier. Here we are creating an instance of JstlView and setting the JSP page that we need to be rendered. Listing 2-6. HomeController View implementation @Controller public class HomeController { @RequestMapping("/home.html") public View showHomePage() { JstlView view = new JstlView(); view.setUrl("/WEB-INF/pages/home.jsp"); return view; }

} Controller implementations typically don't deal with view instances. Instead, they return logical view names, as shown in Listing 2-1, and let view resolvers determine and create view instances. This decouples the controllers from tying to a specific view implementation and makes it easy to swap view implementations. Also, the controllers no longer need to know intricacies such as the location of the views.

@RequestParam The @RequestParam annotation is used to bind Servlet request parameters to handler/controller method parameters. The request parameter values are automatically converted to the specified method parameter type using type conversion. Listing 2-7 shows two usages of @RequestParam. In the first usage, Spring looks for a request parameter named query and maps its value to the method parameter query. In the second usage, Spring looks for a request parameter named page, converts its value to an integer, and maps it to the pageNumber method parameter. Listing 2-7. RequestParam Usage @RequestMapping("/search.html") public String search(@RequestParam String query, @RequestParam("page") int pageNumber) { model.put("currentDate", new Date()); return "home"; } When a method parameter is annotated using @RequestParam, the specified request parameter must be available in the client request. If the parameter is missing, Spring will throw a MissingServletRequestParameterException exception. One way to address this is to set the required attribute to false, as shown in Listing 2-8. The

other option is to use the defaultValue attribute to specify a default value. Listing 2-8. Making a request parameter not required @RequestMapping("/search.html") public String search(@RequestParam String query, @RequestParam(value="page", required=false) int pageNumber) { model.put("currentDate", new Date()); return "home"; }

@RequestMapping As we learned in the “Controller” section, the @RequestMapping annotation is used to map a Web request to a handler class or handler method. @RequestMapping provides several attributes that can be used to narrow down these mappings. Table 2-2 shows the different elements along with their descriptions. Table 2-2. RequestMapping Elements Element Name

Description

Method

Restricts a mapping to a specific HTTP method such as GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE

Produces

Narrows mapping to media type that is produced by the method

Consumes

Narrows mapping to media type that the method consumes

Headers

Narrows mapping to the headers that should be present

name

Allows you to assign a name to the mapping

params

Restricts a mapping to the supplied parameter name and value

The default HTTP method mapped by @RequestMapping is GET. This behavior can be changed using the method element shown in Listing 2-9. Spring invokes the saveUser method only when a POST operation is performed. A GET request on saveUser will result in an exception thrown. Spring provides a handy RequestMethod enumeration with the list of HTTP methods available. Listing 2-9. POST method example @RequestMapping(value="/saveuser.html", method=RequestMethod.POST) public String saveUser(@RequestParam String username, @RequestParam String password) { // Save User logic return "success";

} The produces element indicates the media type, such as JSON or XML or HTML, produced by the mapped method. The produces element can take a single media type or multiple media types as its value. Listing 2-10 shows the search method with the produces element added. The MediaType.TEXT_HTML value indicates that when a GET request is performed on search.html, the method returns an HTML response. Listing 2-10. Produces element example @RequestMapping(value="/search.html", method=RequestMethod.GET, produces="MediaType. TEXT_HTML") public String search(@RequestParam String query, @RequestParam(value="page", required=false) int pageNumber) { model.put("currentDate", new Date()); return "home"; } It is possible for the client to perform a GET request on /search.html but send an Accept header with value application/JSON. In that scenario, Spring will not invoke the search method. Instead, it will return a 404 error. The produces element provides a convenient way to restrict mappings to content types that the controller can serve. In the same fashion, the consumes element is used to indicate the media type that the annotated method consumes.

ACCEPT AND CONTENT-TYPE HEADER As discussed in Chapter 1, REST resources can have multiple representations. REST clients typically use the Accept and Content-Type headers to work with these representations. REST clients use the Accept header to indicate the representations that they accept. The HTTP specification allows a client to send a prioritized list of different media types that it will accept as responses. On receiving the request, the server will send the representation with the highest priority. To understand this, consider the default Accept header for Firefox browser: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 The q parameter, also known as relative quality parameter, indicates the degree of preference and has values ranging from 0 to 1. From the string, we can infer that the HTML and XHTML will have a priority of 1 because they don't have an associated q value. The XML media type has priority 0.9 and the rest of the representations have a priority of 0.8. On receiving this request, the server would try to send a HTML/XHTML representation because it has the highest priority. In a similar fashion, REST clients use the Content-type header to indicate the media type of the request being sent to the server. This allows the server to properly

interpret the request and parse the contents correctly. If the server is unable to parse the content, it will send a 415 Unsupported Media Type error status code. Spring Web MVC allows flexible signatures for methods annotated with @RequestMapping. This includes variable method parameters and method return types. Table 2-3 lists the important arguments allowed. For a detailed list of allowed arguments, refer to Spring's Javadocs at http://docs.spring.io/spring/docs/current/javadocapi/org/springframework/web/bind/annotation/RequestMapping.html Table 2-3. Method arguments and descriptions Method Argument

Description

HttpServletRequest/HttpServletResponse

HTTP Servlet request and response objects. Allows raw access to client’s data, such as request parameters and headers.

HttpSession

Instance representing a user’s HTTP session.

Command Object

A POJO or model object that Spring populates/binds with the user submitted data. The command object can be annotated with @ModelAttribute.

BindingResult

Instance representing a command object’s validation and binding. This parameter must immediately precede the command object.

HttpEntity

Instance representing a HTTP request. Each HttpEntity is composed of request body and a set of headers.

Principal

A java.security.Principal instance that represents the authenticated user.

The different return types supported in methods annotated with @RequestMapping are shown in Table 2-4. Table 2-4. Return types and descriptions Return Type

Description

String

Represents the logical view name. Registered view resolvers are employed to resolve the physical view and a response is generated.

View

Instance representing a view. In this case, no view resolution is performed and the view object is responsible for generating the response. Examples include JstlView, VelocityView, RedirectView, and so on.

HttpEntity

Instance representing a HTTP response. Each HttpEntity is composed of response body and a set of headers.

HttpHeaders

Instance capturing the headers to be returned. Response will have an empty body.

Pojo

Java object that is considered to be a model attribute. A specialized RequestToViewNameTranslator is used to determine the appropriate logical view name.

Path Variables The @RequestMapping annotation supports dynamic URIs via URI templates. As discussed in Chapter 1, URI templates are URIs with placeholders or variables. The @PathVariable annotation allows you to access and use these placeholders via method parameters. Listing 2-11 gives an example of @PathVariable. In this scenario, the getUser method is designed to serve user information associated with the path variable {username}. The client would perform a GET on the URL /users/jdoe to retrieve user information associated with username jdoe. Listing 2-11. PathVariable example @RequestMapping("/users/{username}") public User getUser(@PathVariable("username") String username) { User user = null; // Code to construct user object using username return user; }

View Resolver As discussed in the previous sections, a Spring Web MVC controller can return an org.springframework.web.servlet.View instance or a logical view name. When a logical view name is returned, a ViewResolver is employed to resolve the view to a View implementation. If this process fails for some reason, a javax.servlet.ServletException is thrown. The ViewResolver interface has a single method and is shown in Listing 2-12. Listing 2-12. ViewResolver Interface public interface ViewResolver { View resolveViewName(String viewName, Locale locale) throws Exception; } Table 2-5 lists some of the ViewResolver implementations provided by Spring Web MVC. Table 2-5. ViewResolver implementations and descriptions Return Type

Description ViewResolver implementation that looks for a bean with

BeanNameViewResolver

an id that matches the logical view name in the ApplicationContext. If it doesn't find the bean in the ApplicationContext, a null is returned.

InternalResourceViewResolver

ViewResolver that looks for an internal resource that has the logical view name. The location of the internal resource is typically computed by prefixing and suffixing the logical name with path and extension information.

ContentNegotiatingViewResolver

ViewResolver that delegates the view resolution to other view resolvers. The choice of the view resolver is based on the requested media type, which itself is determined using an Accept header or file extension or URL parameter.

TilesViewResolver

ViewResolver that looks for a template in the Tiles configuration that matches the logical view name.

As you might have noticed, the different view resolvers in Table 2-5 mimic the different types of views we looked at earlier. Listing 2-13 shows the code required for creating an InternalViewResolver. Listing 2-13. InternalViewResolver example @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/jsp/"); viewResolver.setSuffix(".jsp"); return viewResolver; }

Exception Handler Exceptions are part of any application and Spring provides the HandlerExceptionResolver mechanism for handling those unexpected exceptions. The HandlerExceptionResolver abstraction is similar to the ViewResolver and is used to resolve exceptions to error views. Listing 2-14 shows the HandlerExceptionResolver API. Listing 2-14. HandlerExceptionResolver API public interface HandlerExceptionResolver { ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex); } Spring provides several out-of-the-box implementations of HandlerExceptionResolver, as shown in Table 2-6. Table 2-6. HandlerExceptionResolver implementations and descriptions

Resolver Implementation

Description

org.springframework.web.servlet.handlerS. impleMappingExceptionResolver

Exception resolver implementation that maps exception class names to view names.

org.springframework.web.servlet.mvc.support. DefaultHandlerExceptionResolver

Exception resolver implementation that translates standard Spring exceptions to HTTP status codes.

org.springframework.web.servlet.mvc. annotation.ResponseStatusExceptionResolver

Custom exceptions in Spring applications can be annotated with @ResponseStatus, which takes a HTTP status code as its value. This exception resolver translates the exceptions to its mapped HTTP status codes.

org.springframework.web.servlet.mvc.method. annotation.ExceptionHandlerExceptionResolver

Exception resolver implementation that resolves exceptions using annotated @ExceptionHandler methods.

The SimpleMappingExceptionResolver has been around for a really long time. Spring 3 introduced a new way of handling exceptions using the @ExceptionHandler strategy. This provides a mechanism for handling errors in REST-based services where there is really no view to show but, rather, return data. Listing 2-15 shows a controller with an exception handler. Any methods that now throw a SQLException in the HomeController will get handled in the handleSQLException method. The handleSQLException simply creates a ResponseEntity instance and returns it. However, additional operations such as logging, returning additional diagnostic data, and so on can be performed. Listing 2-15. ExceptionHandler example @Controller public class HomeController { @ExceptionHandler(SQLException.class) public ResponseEntity handleSQLException() { ResponseEntity responseEntity = new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR); return responseEntity; } @RequestMapping("/stream") public void streamMovie(HttpServletResponse response) throws SQLException { }

} The @ExceptionHandler annotated methods can only handle exceptions that

occur in the controller or its subclasses. So, if we need to handle SQL exceptions in other controllers, then we need to copy and paste the handleSQLException method in all of those controllers. This approach can pose severe limitations, as exception handling is truly a crosscutting concern and should be centralized. To address this, Spring provides the @ControllerAdvice annotation. Methods in classes annotated with @ControllerAdvice get applied to all the @RequestMapping methods. Listing 2-16 shows the GlobalExceptionHandler with the handleSQLException method. As you can see, the GlobalExceptionHandler extends Spring's ResponseEntityExceptionHandler, which converts default Spring Web MVC exceptions to a ResponseEntity with HTTP status codes. Listing 2-16. GlobalExceptionHandler example @ControllerAdvice public class GlobalExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler(SQLException.class) public ResponseEntity handleSQLException() {

ResponseEntity responseEntity = new ResponseEntity(HttpStatus.INTERNAL_SERVER_ERROR); return responseEntity; } }

Interceptors Spring Web MVC provides the notion of interceptors to implement concerns that crosscut across different handlers. Consider the scenario in which you want to prevent unauthenticated access to a set of controllers. An interceptor allows you to centralize this access logic without you having to copy and paste the code in every controller. As the name suggests, interceptors intercept a request; they do so at the following three points: Before the controller gets executed. This allows the interceptor to decide if it needs to continue the execution chain or return with an exception or custom response. After the controller gets executed but before the response is sent out. This allows the interceptor to provide any additional model objects to the view. After the response is sent out allowing any resource cleanup. Note Spring Web MVC interceptors are similar to HTTP servlet filters. Both can be used to intercept a request and execute common concerns. However, there are a few differences between them that are worth noting. Filters have the capability to wrap or even

swap the HttpServletRequest and HttpServletResponse objects. Interceptors can’t decorate or swap those objects. Interceptors are Spring-managed beans, and we can easily inject other spring beans in them. Filters are container-managed instances; they don't provide a straightforward mechanism for injecting Spring-managed beans. Spring Web MVC provides the HandlerInterceptor interface for implementing interceptors. Listing 2-17 gives the HandlerInterceptor interface. As you can see, the three methods correspond to the three interceptor features that we just discussed. Listing 2-17. HandlerInterceptor API public interface HandlerInterceptor{ void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex); void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView); boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler); } Listing 2-18 gives a simple interceptor implementation. As you can see, the SimpleInterceptor class extends HandlerInterceptorAdapter. The HandlerInterceptorAdapter is a convenient abstract class that implements the HandlerInterceptor interface and provides default implementations of its methods. Listing 2-18. Spring Web MVC Interceptor example public class SimpleInterceptor extends HandlerInterceptorAdapter { private static final Logger logger = Logger.getLogger(SimpleInterceptor.class); public boolean preHandle(HttpServletRequest request,

HttpServletResponse response, Object handler) throws Exception { logger.info("Inside the prehandle"); return false; }

} Interceptors can be registered in a Spring Web application using the InterceptorRegistry strategy. When using Java Configuration, this is typically achieved by creating a configuration class that extends WebMvcConfigurerAdapter. Spring Web MVC’s WebMvcConfigurerAdapter class provides the addInterceptors method that can be used to access the InterceptorRegistry. Listing 2-19 shows the code registering two interceptors: LocalInterceptor that

comes out of the box with Spring and our SimpleInterceptor. Listing 2-19. Example registering interceptors @Configuration @EnableWebMvc @ComponentScan(basePackages = { "com.apress.springrest.web" }) public class WebConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry)

{ registry.addInterceptor(new LocaleChangeInterceptor()); registry.addInterceptor(new SimpleInterceptor()).addPathPatterns("/auth/**"); }

} When an interceptor is added to the interceptor registry, the interceptor gets applied to all of the handler mappings. So, the LocaleChangeInterceptor in Listing 2-19 gets applied to all the handler mappings. However, it is also possible to restrict the interceptor to certain URLs. This is demonstrated in Listing 2-19 using the addPathPatterns method. Here we are indicating that the SimpleInterceptor should be applied to only the URLs that are under the auth path.

Summary In this chapter, we have looked at the basics of the Spring Framework and different components of a Spring Web MVC. In the next chapter, we will bring things together and look at building our first RESTful application using Spring Boot. _____________________ 1http://martinfowler.com/articles/injection.html. 2http://www.oracle.com/technetwork/java/frontcontroller-135648.html.

CHAPTER 3

RESTful Spring In this chapter, we will discuss: The basics of Spring Boot Building a Hello World REST application Tools for accessing REST applications One of the Spring Framework’s goals is to reduce plumbing code so that developers can focus their efforts on implementing core business logic. However, as the Spring Framework evolved and added several subprojects to its portfolio, developers ended up spending a considerable amount of time setting up projects, finding project dependencies, and writing boiler plate code and configuration. Spring Boot, a Spring portfolio project aims at simplifying Spring application bootstrapping by providing a set of starter project templates. These would pull all the proper dependencies that are needed based on project capabilities. For example, if you enable JPA capability, it automatically includes all the dependent JPA, Hibernate, and Spring JAR files. Spring Boot also takes an opinionated approach and provides default configuration that simplifies application development quite a bit. For example, if Spring Boot finds JPA and MySQL JARs in the classpath, it would automatically configure a JPA Persistence Unit. It also enables creation of standalone Spring applications with embedded Jetty/Tomcat servers, making them easy to deploy on any machine with just Java installed. Additionally, it provides production-ready features such as metrics and health checks. Throughout this book, we will be exploring and learning these and additional features of Spring Boot. Note Spring Roo is another Spring portfolio project that attempts to provide rapid Spring application development. It provides a command-line tool that enables easy project bootstrapping and generates code for components such as JPA entities, Web controllers, test scripts, and necessary configuration. Although there was a lot of initial interest in the project, Spring Roo never really became mainstream. AspectJ Code generation and a steep learning curve coupled with its attempt to take over your project are some reasons for lack of its adoption. Spring Boot, by contrast, takes a different approach; it focuses on jump starting the project and providing clever, sensible, default configuration. It doesn’t generate any code and can easily be removed.

Generating a Spring Boot Project It is possible to create a Spring Boot project from scratch. However, Spring Boot provides the following options to generate a new project: Use Spring Boot’s starter website (http://start.spring.io) Use the Spring Tool Suite (STS) IDE Use the Boot command line interface (CLI) We will explore all three alternatives in this chapter. However, for the rest of the book we will be opting for the Boot CLI to generate new projects. Before we start with project generation, it is important that Java is installed on your machine. Spring Boot requires that you have Java SDK 1.6 or higher installed. In this book we will be using Java 1.7.

Installing a Build Tool Spring Boot supports the two most popular build systems: Maven and Gradle. In this book we will be using Maven as our build tool. Spring Boot requires Maven version 3.2 or higher. The steps to download and configure Maven on your Windows machine are given here. Similar instructions for Mac and other operating systems can be found on Maven’s download page (http://maven.apache.com/download.cgi): 1. Download the latest Maven binary from http://maven.apache.org/download.cgi. At the time of writing this book, the current version of Maven was 3.2.5. For Windows, download the apache-maven-3.2.5-bin.zip file. 2. Unzip the contents of the zip file under C:\tools\maven. 3. Add an Environment variable M2_HOME with value C:\tools\maven\apache-maven-3.2.5-bin\apachemaven-3.2.5. This tells Maven and other tools where Maven is installed. Also make sure that the JAVA_HOME variable is pointing to the installed JDK. 4. Append the value %M2_HOME%\bin to the Path environment variable. This allows you to run Maven commands from the command line. 5. Open a new command line and type the following: mvn - v You should see an output similar to Figure 3-1, indicating that Maven was successfully installed.

Figure 3-1. Maven installation verification

Note To learn more about Maven, refer to Introducing Maven, published by Apress (http://www.apress.com/9781484208427).

Generating a Project using start.spring.io Spring Boot hosts an Initializr application at http://start.spring.io. The Initializr provides a Web interface that allows you to enter project information, pick the capabilities needed for your project, and voilà—it generates the project as a zip file. Follow these steps to generate our Hello World REST application: 1. Launch the http://start.spring.io website in your browser and enter the information shown in Figure 3-2.

Figure 3-2. start.spring.io website

2. Under Project dependencies Web, select the option “Web” and indicate that you would like Spring Boot to include Web project infrastructure and dependencies. 3. Then hit the “Generate Project” button. This will begin the hellorest.zip file download. On completion of the download, extract the contents of the zip file. You will see the hello-rest folder generated. Figure 3-3 shows the contents of the generated folder.

Figure 3-3. hello-rest application contents

A quick look at the hello-rest contents shows that we have a standard Mavenbased Java project layout. We have the src\main\java folder, which houses Java source code; src\main\resources, which contains property files; static content, such as HTML\CSS\JS files; and the src\test\java folder, which contains the test cases. On running a Maven build, this project generates a JAR artifact. Now, this might be little confusing for the first-timer who is used to WAR artifacts for deploying Web applications. By default, Spring Boot creates standalone applications in which everything gets packaged into a JAR file. These applications will have embedded servlet containers such as Tomcat and are executed using a good old main() method. Note Spring Boot also allows you to work with WAR artifacts that can be deployed to external Web and application containers. Listing 3-1 gives the contents of the hello-rest application’s pom.xml file. Listing 3-1. hello-rest pom.xml file contents 4.0.0 com.apress hello-rest 0.0.1-SNAPSHOT jar

Hello World REST Hello World REST Application Using Spring

Boot
org.springframework.boot spring-boot-starter-

parent
1.2.1.RELEASE
UTF-

8
com.apress.hellorest.HelloWorldRestApplication 1.7


org.springframework.boot spring-boot-starterweb


org.springframework.boot spring-boot-startertest test


org.springframework.boot spring-boot-mavenplugin


The groupId, artifactId, and version elements in the pom.xml file correspond to Maven’s standard GAV coordinates describing our project. The parent tag indicates that we will be inheriting from the spring-boot-starter-parent POM. This ensures that our project inherits Spring Boot’s default dependencies and versions. The dependencies element lists two POM file dependencies: spring-bootstarter-web and spring-boot-starter-test. Spring Boot uses the term starter POMs to describe such POM files. These starter POMs are used to pull other dependencies and don’t actually contain any code of their own. For example, the spring-boot-starter-web pulls Spring MVC dependencies, Tomcat-embedded container dependencies, and a Jackson dependency for JSON processing. These starter modules play an important role in providing needed dependencies and simplifying the application’s POM file to just a few lines. Table 3-1 lists some of the commonly used starter modules. Table 3-1. Spring Boot Starter Modules Starter POM Dependency

Use

spring-bootstarter

Starter that brings in core dependencies necessary for functions such as autoconfiguration support and logging

spring-bootstarter-aop

Starter that brings in support for aspect-oriented programming and AspectJ

spring-bootstarter-test

Starter that brings in dependencies such as JUnit, Mockito, and spring-test necessary for testing

spring-bootstarter-web

Starter that brings in MVC dependencies (spring-webmvc) and embedded servlet container support

spring-bootstarter-data-jpa

Starter that adds Java Persistence API support by bringing in spring-datajpa, spring-orm and Hibernate dependencies

spring-bootstarter-data-rest

Starter that brings in spring-data-rest-webmvc to expose repositories as REST API

spring-bootstarter-hateoas

Starter that brings in spring-hateoas dependencies for HATEOAS REST services

spring-bootstarter-jdbc

Starter for supporting JDBC databases

Finally, the spring-boot-maven-plugin contains goals for packaging the application as an executable JAR/WAR and running it. The HelloWorldRestApplication.java class serves as the main class for our application and contains the main() method. Listing 3-2 shows the contents of the HelloWorldRestApplication.java class. The @SpringBootApplication annotation is a convenient annotation and is equivalent to declaring the following three

annotations: @Configuration—Marks the annotated class as containing one or more Spring bean declarations. Spring processes these classes to create bean definitions and instances. @ComponentScan—This class tells Spring to scan and look for classes annotated with @Configuration, @Service, @Repository, and so on. By default, Spring scans all the classes in the package where the @ComponentScan annotated class resides. @EnableAutoConfiguration—Enables Spring Boot’s autoconfiguration behavior. Based on the dependencies and configuration found in the classpath, Spring Boot intelligently guesses and creates bean configurations. Typical Spring Boot applications always use these three annotations. In addition to providing a nice alternative in those scenarios, the @SpringBootApplication annotation correctly denotes the class’s intent. Listing 3-2. HelloWorldRestApplication contents package com.apress.hellorest; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class HelloWorldRestApplication { public static void main(String[] args) { SpringApplication.run(HelloWorldRestApplication.class,

args); } } The main() method simply delegates the application bootstrapping to SpringApplication’s run() method. run() takes a HelloWorldRestApplication.class as its argument and instructs Spring to read annotation metadata from HelloWorldRestApplication and populate ApplicationContext from it. Now that we have looked at the generated project, let’s create a REST endpoint that simply returns “Hello REST”. Ideally, we would create this endpoint in a separate controller Java class. However, to keep things simple, we will create the endpoint in HelloWorldRestApplication, as shown in Listing 3-3. We start by adding the @RestController, indicating that HelloWorldRestApplication has possible

REST endpoints. We then create the helloGreeting() method, which simply returns the greeting “Hello REST”. Finally, we use the RequestMapping annotation to map Web requests for “/greet” path to helloGreeting() handler method. Listing 3-3. Hello REST Endpoint package com.apress.hellorest; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RequestMapping; @SpringBootApplication @RestController public class HelloWorldRestApplication { public static void main(String[] args) { SpringApplication.run(HelloWorldRestApplication.class,

args); } @RequestMapping("/greet") public String helloGreeting() { return "Hello REST"; }

} The next step is to launch and run our application. To do this, open a command line, navigate to the hello-rest folder, and run the following command: mvn spring-boot:run You will see Maven downloading the necessary plugins and dependencies, and then it will launch the application, as shown here: . ____ _ __ _ _ /\ / ___’_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | ‘_ | ‘_| | ‘_ \/ _` | \ \ \ \ \/ ___)| |_)| | | | | || (_| | ) ) ) ) ‘ |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v1.2.1.RELEASE) 2015-01-25 22:13:19.094 INFO 1468 – [lication.main()]

ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbedde startup date [Sun Jan 25 22:13:19 MST 2015]; root of context hierarchy 2015-01-25 22:13:20.315 INFO 1468 – [lication.main()] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http) 2015-01-25 22:13:20.672 INFO 1468 – [lication.main()] o.apache.catalina.core.StandardService : Starting service Tomcat 2015-01-25 22:13:20.673 INFO 1468 – [lication.main()] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.0.15 2015-01-25 22:13:20.753 INFO 1468 – [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2015-01-25 22:13:20.754 INFO 1468 – [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1660 ms 2015-01-25 22:13:21.895 INFO 1468 – [lication.main()] c.a.hellorest.HelloWorldRestApplication : Started HelloWorldRestApplication in 3.081 seconds (JVM running for 11.783) To test our running application, launch a browser and navigate to http://localhost:8080/greet. Notice that Spring Boot launches the application as the ROOT context and not the hello-world context. You should see a screen similar to that in Figure 3-4.

Figure 3-4. Hello REST greeting

SPRING INITIALIZR The Spring Initializr application hosted at http://start.spring.io itself is built using Spring Boot. You can find the source code of this application on GitHub at https://github.com/spring-io/initializr. It is also possible for you to build and host your own instances of the Initializr application.

In addition to providing a Web interface, the Initializr provides a HTTP endpoint that provides similar project generation capability. In fact, Spring Boot’s CLI and IDEs such as STS use this HTTP endpoint behind the scenes for generating projects. The HTTP endpoint can also be invoked from the command line using curl. For example, the following command would generate the hello-rest project zip file using curl. The –d options are used to provide data that gets passed as request parameters: curl https://start.spring.io/starter.zip -d style=web -d name=hello-rest

Generating a Project using STS Spring Tool Suite or STS is a free Eclipse-based development environment that provides great tooling support for developing Spring-based applications. You can download and install the latest version of STS from Pivotal’s website at: https://spring.io/tools/sts/all. At the time of writing this book, the current version of STS was 3.6.3. STS provides a user interface similar to Initializr’s web interface for generating Boot starter projects. Here are the steps for generating a Spring Boot project: 1. Launch STS if you haven’t already done so. Go to File New and click on Spring Starter Project, as shown in Figure 3-5.

Figure 3-5. STS Spring starter project

2. In following screen, enter the information as shown in Figure 3-6. In addition to entering Maven’s GAV information, select the Web starter option. Hit Next.

Figure 3-6. Starter project options

3. On the following screen, change the location where you would like to store the project. The “Full Url” area shows the HTTP REST endpoint along with the options that you selected (see Figure 3-7).

Figure 3-7. Starter project location

4. Hit the Finish button and you will see the new project created in STS. The contents of the project are similar to the project that we created earlier (see Figure 3-8).

Figure 3-8. STS Spring starter project resources

STS’s starter project wizard provides a convenient way to generate new Spring Boot projects. The newly created project automatically gets imported into the IDE and is immediately available for development.

Generating a Project Using the CLI Spring Boot provides a command line interface (CLI) for generating projects, prototyping, and running Groovy scripts. Before we can start using the CLI, we need to install it. Here are the steps for installing the Boot CLI on a Windows machine:

1. Download the latest version of the CLI ZIP distribution from Spring’s website at http://repo.spring.io/release/org/springframework/boot/ boot-cli. At the time of writing this book, the current version of CLI was 1.2.1. This version can be downloaded directly from

http://repo.spring.io/release/org/springframework/boot/ boot-cli/1.2.1.RELEASE/spring-boot-cli1.2.1.RELEASE-bin.zip. 2. Extract the zip file and place its contents (folders such as bin and lib) under C:\tools\springbootcli, as shown in Figure 39.

Figure 3-9. Spring Boot CLI contents

3. Add a new environment variable SPRING_HOME with value c:\tools\springbootcli. 4. Edit the Path environment variable and add the %SPRING_HOME%/bin value to its end. 5. Open a new command line and verify the installation running the following command: spring --version You should see an output similar to that shown in Figure 3-10.

Figure 3-10. Spring Boot CLI installation

Now that we have the Boot CLI installed, generating a new project simply involves running the following command at the command line: spring init --dependencies web rest-cli The command creates a new rest-cli project with Web capability. The output of running the command is shown in Listing 3-4. Listing 3-4. Boot CLI Output C:\test>spring init --dependencies web rest-cli Using service at https://start.spring.io Project extracted to 'C:\test\rest-cli'

Accessing REST Applications There are several free and commercial tools that allow you to access and experiment with REST API/applications. In this section we will look at some of the popular tools that allow you to quickly test a request and inspect the response.

Postman Postman is a Chrome browser extension for making HTTP requests. It offers a plethora of features that makes it easy to develop, test, and document a REST API. A Chrome app version of Postman is also available that provides additional features such as bulk uploading that are not available in the browser extension. Postman can be downloaded and installed from the Chrome Web Store. To install Postman, simply launch the Chrome browser and navigate to https://chrome.google.com/webstore/detail/postman-restclient/fdmmgilgnpjigdojojpjoooidkmcomcm. You might be asked to log in to your Google Chrome account and confirm using the “New app” installation dialog. On completion of the installation, you should be able to locate and launch Postman using the “Apps icon” in the Bookmarks bar or by typing chrome://apps/shortcut. Figure 3-10 shows Postman launched in the Chrome browser. Postman provides a clean intuitive user interface for composing an HTTP request, sending it to a server, and viewing the HTTP response. It also automatically saves the requests, which are readily available for future runs. Figure 3-11 shows a HTTP GET request made to our Greet service and its response. You can also see the request saved in the History section of the left sidebar.

Figure 3-11. Postman browser extension

Postman makes it easy to logically group related API calls into collections, as shown in Figure 3-12. It is possible to have subcollections of requests under a collection.

Figure 3-12. Postman collections

RESTClient RESTClient is a Firefox extension for accessing REST APIs and applications. Unlike Postman, RESTClient doesn’t have a lot of bells and whistles, but it provides basic functionality to quickly test a REST API. To install RESTClient, launch the Firefox browser and navigate to the URL https://addons.mozilla.org/enUS/firefox/addon/restclient/. Then click the “+ Add to Firefox” button and in the following “Software Installation” dialog click the “Install Now” button. On completion of the installation, you can launch RESTClient using the RESTClient icon on the top right corner of the browser. Figure 3-13 shows the RESTClient application with a request to our Greet service and the corresponding response.

Figure 3-13. RESTClient

Summary Spring Boot provides an opinionated approach to building Spring-based applications. In this chapter, we looked at Spring Boot’s features and used it to build a Hello World REST application. We also looked at the Postman and RESTClient tools for testing and exploring the REST API. In the next chapter, we will begin work on a more complex REST application and discuss the process of identifying and designing resources.

CHAPTER 4

Beginning QuickPoll Application In this chapter we will discuss: Analyzing the requirements for QuickPoll Identifying QuickPoll resources Designing representations Implementing QuickPoll Up to this point, we have looked at the fundamentals of REST and reviewed our technology choice of implementation—Spring MVC. Now it’s time to develop a more complex application. In this chapter, we will introduce you to the beginnings of an application that we will be working on throughout this book. We will call it QuickPoll. We will go through the process of analyzing the requirements, identifying resources, designing their representation, and, finally, provide an implementation to a subset of features. In upcoming chapters, we will continue our design and implementation by adding new features, documentation, security, and versioning.

Introducing QuickPoll Polls have become a popular option for soliciting views and opinions from the community on many websites these days. There are a couple of variations between online polls, but a poll typically has a question and a list of answers, as shown in Figure 4-1.

Figure 4-1. Web poll example

Participants vote and communicate their opinion by selecting one or more responses. Many polls also allow participants to view the poll results, as shown in Figure 4-2.

Figure 4-2. Web poll results

Imagine being part of QuickPoll Inc., a budding Software as a Service, or SaaS, provider that allows users to create, manipulate, and vote on polls. We plan to launch our services to a small audience, but we intend to become a global enterprise. In addition to the Web, QuickPoll would also like to target native iOS and Android platforms. To achieve these lofty goals, we have chosen to implement our application using REST principles and Web technologies. We begin the development process by analyzing and understanding requirements. Our QuickPoll application has the following requirements: Users interact with QuickPoll services to create new polls Each poll contains a set of options that are provided during poll creation Options inside a poll can be updated at a later point To keep things simple, QuickPoll restricts voting on a single option Participants can cast any number of votes Results of a poll can be viewed by anyone We have started with a simple set of requirements for QuickPoll. As with any other application, these requirements will evolve and change. We will address those changes in upcoming chapters.

Designing QuickPoll As discussed in Chapter 1, designing a RESTful application typically involves the following steps: 1. Resource Identification 2. Resource Representation 3. Endpoint Identification

4. Verb/Action Identification

Resource Identification We begin the resource identification process by analyzing requirements and extracting nouns. At a high level, the QuickPoll application has users that create and interact with polls. From the previous statement, you can identify User and Poll as nouns and classify them as resources. Similarly, users can vote on polls and view the voting results, making Vote another resource. This resource modeling process is similar to database modeling in that it is used to identify entities or object-oriented design that identifies domain objects. It is important to remember that all nouns identified need not be exposed as resources. For example, a poll contains several options, making Option another candidate for resource. Making Poll Option a resource would require a client to make two GET requests. The first request will obtain a Poll representation; the second request will obtain an associated Options representation. However, this approach makes the API chatty and might overload servers. An alternative approach is to include the options inside a Poll representation, thereby hiding Option as a resource. This would make Poll a coarsegrained resource, but clients would get poll-related data in one call. Additionally, the second approach can enforce business rules such as requiring at least two options for a poll to be created. This noun approach allows us to identify collection resources. Now, consider the scenario in which you want to retrieve all of the votes for a given poll. To handle this, you need a “votes” collection resource. You can perform a GET request and obtain the entire collection. Similarly, we need a “polls” collection resource, which allows us to query groups of polls and create new ones. Finally, we need to address the scenario in which we count all of the votes for a poll and return the computed results to the client. This involves looping through all the votes for a poll, grouping those votes based on options, and then counting them. Such processing operations are typically implemented using a “controller” resource, which we introduced in Chapter 1. In this case, we model a ComputeResult resource, which performs this counting operation. Table 4-1 shows the identified resources and their collection resource counterparts. Table 4-1. Resources for QuickPoll application Resource

Description

User

Singleton User Resource

Users

Collection User Resource

Poll

Singleton Poll Resource

Polls

Collection Poll Resource

Vote

Singleton Vote Resource

Votes

Collection Vote Resource

ComputeResult

Count Processing Resource

Resource Representation The next step in the REST API design process is defining resource representations and representation formats. REST APIs typically support multiple formats such as HTML, JSON, and XML. The choice of the format largely depends on the API audience. For example, a REST service that is internal to the company might only support JSON format, whereas a public REST API might speak XML and JSON formats. In this chapter and in the rest of the book, JSON will be the preferred format for our operations.

JSON FORMAT The JavaScript Object Notation, or JSON, is a lightweight format for exchanging information. Information in JSON is organized around two structures: objects and arrays. A JSON object is a collection of name/value pairs. Each name/value pair consists of a field name in double quotes followed by a colon (:), followed by a field value. JSON supports several types of values such as Boolean (true or false), number (int or float), String, null, arrays, and object. Examples of name/value pairs include: “country” : “US” “age” : 31 “isRequired” : true “email” : null JSON objects are surrounded by curly braces ({}), and each name/value pair is separated using a comma (,). Here is an example of a person JSON object: { “firstName”: “John”, “lastName”: “Doe”, “age” : 26, “active” : true } The other JSON structure, an array, is an ordered collection of values. Each array is surrounded by square brackets ([]), with values separated by a comma. Here is an example of an array of locations: [ “Salt Lake City”, “New York”, “Las Vegas”, “Dallas”] JSON arrays can also contain objects as their values: [ { “firstName”: “Jojn”, “lastName”: “Doe”, “age”:

26, “active”: true }, { “firstName”: “Jane”, “lastName”: “Doe”, “age”: 22, “active”: true }, { “firstName”: “Jonnie”, “lastName”: “Doe”, “age”: 30, “active”: false } ] Resources are made up of set of attributes that can be identified using process similar

to Object Oriented design. A Poll resource, for example, has a question attribute, containing a Poll question, and an id attribute, which uniquely identifies the Poll. It also contains a set of options; each option is made up of a value and an id. Listing 4-1 shows a representation of a Poll with sample data. Listing 4-1. Poll representation { "id": 2, "question": "How will win SuperBowl this year?", "options": [{"id": 45, "value": "New England

Patriots"}, {"id": 49, "value": "Seattle Seahawks"}, {"id": 51, "value": "Green Bay Packers"}, {"id": 54, "value": "Denver Broncos"}] } Note We are intentionally excluding a user from Poll representation in this chapter. In Chapter 8, we will discuss User representation along with its associations to Poll and Vote resources. The representation of a Poll collection resource contains a collection of individual polls. Listing 4-2 gives the representation of a Polls collection resource with dummy data. Listing 4-2. List of Polls representation [ { "id": 5, "question": "q1", "options": [{"id": 6, "value": "X"}, {"id": 9,

"value": "Y"}, {"id": 10, "value": "Z"}] }, { "id": 2, "question": "q10", "options": [{"id": 15, "value": "Yes"}, {"id": 16, "value": "No"}] } ....... ] The Vote resource contains the option for which the vote was cast and a unique identifier. Listing 4-3 shows the Vote resource representation with dummy data. Listing 4-3. Vote representation { "id": 245,

"option": {"id": 45, "value": "New England Patriots"}

} Listing 4-4 gives the Votes collection resource representation with dummy data. Listing 4-4. List of Votes representation [ { "id": 245, "option": {"id": 5, "value": "X"} }, { "id": 110, "option": {"id": 7, "value": "Y"} }, ............

The ComputeResult resource representation should include the total number of votes and Poll options along with the vote count associated with each option. Listing 4-5 shows this representation with sample data. We use the totalVotes attribute to hold the cast votes and the results attribute to hold the option id and the associated votes. Listing 4-5. ComputeResult representation { totalVotes: 100, "results" : [ { "id" : 1, "count" : 10 }, { "id" : 2, "count" : 8 }, { "id" : 3, "count" : 6 }, { "id" : 4, "count" : 4 } ]

} Now that we have defined our resource representation, we will move on to identifying endpoints for those resources.

Endpoint Identification REST resources are identified using URI endpoints. Well-designed REST APIs should have endpoints that are understandable, intuitive, and easy to use. Remember that we build REST APIs for our consumers to use. Hence, the names and the hierarchy that we choose for our endpoints should be unambiguous to consumers. We design the endpoints for our service using best practices and conventions widely used in the industry. The first convention is to use a base URI for our REST service. The base URI provides an entry point for accessing the REST API. Public REST API providers typically use a subdomain such as http://api.domain.com or

http://dev.domain.com as their base URI. Popular examples include GitHub’s https://api.github.com and Twitter’s https://api.twitter.com. By creating a separate subdomain, you prevent any possible name collisions with webpages. It also allows you to enforce security policies that are different from the regular website. To keep things simple, we will be using http://localhost:8080 as our base URI in this book. The second convention is to name resource endpoints using plural nouns. In our QuickPoll application, this would result in an endpoint http://localhost:8080/polls for accessing the Poll collection resource. Individual Poll resources will be accessed using a URI such as http://localhost:8080/polls/1234 and http://localhost:8080/polls/3456. We can generalize access to individual Poll resources using the URI template http://localhost:8080/polls/{pollId}. Similarly, the endpoints http://localhost:8080/users and http://localhost:8080/users/{userId} are used for accessing collection and individual User resources. The third convention advises using a URI hierarchy to represent resources that are related to each other. In our QuickPoll application, each Vote resource is related to a Poll resource. Because we typically cast votes for a Poll, a hierarchical endpoint http://localhost:8080/polls/{pollId}/votes is recommended for obtaining or manipulating all the votes associated with a given Poll. In the same way, the endpoint http://localhost:8080/polls/{pollId}/votes/{voteId} would return an individual vote that was cast for the Poll. Finally, the endpoint http://localhost:8080/computeresult can be used to access the ComputeResult resource. For this resource to function properly and count the votes, a poll id is required. Because the ComputeResult works with Vote, Poll, and Option resources, we can’t use the third approach for designing a URI that is hierarchal in nature. For use cases like these that require data to perform computation, the fourth convention recommends using a query parameter. For example, a client can invoke the endpoint http://localhost:8080/computeresult?pollId=1234 to count all of the votes for the Poll with id 1234. Query parameters are an excellent vehicle for providing additional information to a resource. In this section, we have identified the endpoints for the resources in our QuickPoll application. The next step is to identify the actions that are allowed on these resources, along with the expected responses.

Action Identification HTTP Verbs allow clients to interact and access resources using their endpoints. In our QuickPoll application, the clients must be able to perform one or more CRUD operations on resources such as Poll and Vote. Analyzing the use cases from the “Introducing QuickPoll” section, Table 4-2 shows the operations allowed on Poll/Polls collection

resources along with the success and error responses. Notice that on the Poll collection resource we allow GET and POST operations but deny PUT and Delete operations. A POST on the collection resource allows the client to create new polls. Similarly, we allow GET, PUT, and Delete operations on a given Poll resource but deny POST operation. The service returns a 404 status code for any GET, PUT, and DELETE operation on a Poll resource that doesn’t exist. Similarly, any server errors would result in a status code of 500 sent to the client. Table 4-2. Allowed operations on a Poll resource

In the same fashion, Table 4-3 shows the operations allowed on Vote/Votes collection resources. Table 4-3. Allowed operations on Vote resource

Finally, Table 4-4 shows the operations allowed on the ComputeResult resource. Table 4-4. Allowed operations on ComputeResult resource

This concludes the design for the QuickPoll REST service. Before we start our implementation, we will review QuickPoll’s high-level architecture.

QuickPoll Architecture The QuickPoll application will be made of a Web or REST API layer and a Repository layer with a domain layer crosscutting those two, as depicted in Figure 4-3. A layered approach provides a clear separation of concerns, making applications easy to build and maintain. Each layer interacts with the layer below using a well-defined contract. As long as the contract is maintained, it is possible to swap out underlying implementations without any impact to the overall system.

Figure 4-3. QuickPoll architecture

The Web API layer is responsible for receiving client requests, validating user input, interacting with a service or a repository layer, and generating a response. Using HTTP protocol, resource representations are exchanged between clients and the Web API layer. This layer contains Controllers/Handlers and is typically very lightweight as it delegates most of the work to layers beneath it. The domain layer is considered to be the “heart” of an application. Domain objects in this layer contain business rules and business data. These objects are modeled after the nouns in the system. For example, a Poll object in our QuickPoll application would be considered a domain object. The repository or data access layer is responsible for interacting with a datastore such as a database or LDAP or a legacy system. It typically provides CRUD operations for storing and retrieving objects from/to a datastore.

Note Observant readers will notice that the QuickPoll architecture is missing a service layer. Service layer typically sits between the API/Presentation layer and Repository layer. It contains coarse-grained API with methods that fulfill one or more use cases. It is also responsible for managing transactions and other crosscutting concerns such as security. Because we are not dealing with any complex use cases for QuickPoll application in this book, we will not be introducing service layers into our architecture.

Implementing QuickPoll We begin QuickPoll implementation by generating a Spring Boot project using STS. Follow the steps discussed in the “Generating Project using STS” section of Chapter 3, and create a project named quick-poll. Figure 4-4 gives the configuration information used during project generation. Notice that we have selected the “JPA” and “Web” options.

Figure 4-4. QuickPoll project configuration

Alternatively, you can import the QuickPoll project into your STS IDE from the downloaded source code for this book. The downloaded source code contains a number of folders named ChapterX, in which X represents the corresponding chapter number. Each ChapterX folder further contains two subfolders: a starter folder and a final folder. The starter folder houses a QuickPoll project that you can use to follow along with the solution described in this chapter. Even though each chapter builds on the previous chapter’s work, the starter project allows you to skip around in the book. For example, if you are interested in learning about security, you can simply load the QuickPoll application under the Chapter8\starter folder and follow the solution as described in Chapter 8.

As the name suggests, the final folder contains the completed solution/code for each chapter. To minimize code in the chapter text, I have omitted getters/setters methods, imports and package declarations in some of the code listings. Please refer to the QuickPoll code under the final folder for complete code listings. By default, Spring Boot applications run on port 8080. So, if you intend to run two versions of QuickPoll, simply use the command line option -Dserver.port: mvn spring-boot:run -Dserver.port=8181 Note Java Persistence API, or JPA, is a standards-based API for accessing, storing, and managing data between Java objects and relational database. Like JDBC, JPA is a purely a specification and many commercial and open source products such as Hibernate and TopLink provide JPA implementations. A formal overview of JPA is beyond the scope of this book. Please refer to Pro JPA 2 (http://www.apress.com/9781430219569/) to learn more.

Domain Implementation The domain objects typically act as a backbone for any application. So, the next step in our implementation process is to create domain objects. Figure 4-5 shows a UML Class diagram representing the three domain objects in our QuickPoll application and their relationships.

Figure 4-5. QuickPoll domain objects

Inside the quick-poll project, create a com.apress.domain subpackage under the /src/main/java folder and create Java classes corresponding to the domain objects that we identified. Listing 4-6 gives the implementation of the Option class. As you can see, the Option class has two fields: id, to hold the identity, and value, corresponding to the option value. Additionally, you will see that we have annotated this class with JPA annotations such as @Entity and @Id. This allows instances of the Option class to be easily persisted and retrieved using JPA technology. Listing 4-6. Option class package com.apress.domain; import javax.persistence.Column;

import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; @Entity public class Option { @Id @GeneratedValue @Column(name="OPTION_ID") private Long id; @Column(name="OPTION_VALUE") private String value; // Getters and Setters omitted for brevity

} Next, we create a Poll class, as shown in Listing 4-7, along with corresponding JPA annotations. The Poll class has a question field to store the poll question. The @OneToMany annotation, as the name suggests, indicates that a Poll instance can contain zero or more Option instances. The CascadeType.All indicates that any database operations such as persist, remove, or merge on a Poll instance needs to be propagated to all related Option instances. For example, when a Poll instance gets deleted, all of the related Option instances will be deleted from the database. Listing 4-7. Poll class package com.apress.domain; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToMany; import javax.persistence.OrderBy ; @Entity public class Poll { @Id @GeneratedValue @Column(name="POLL_ID") private Long id;

@Column(name="QUESTION") private String question; @OneToMany(cascade=CascadeType.ALL) @JoinColumn(name="POLL_ID") @OrderBy private Set