Featured resource
pluralsight tech forecast
2025 Tech Forecast

Which technologies will dominate in 2025? And what skills do you need to keep up?

Check it out
Hamburger Icon
  • Labs icon Lab
  • Core Tech
Labs

Guided: Creating a Quotes REST API with Spring Boot 3 - Part 1 - Setup

In this lab, you will complete the configuration of the QuotesController class using Spring Web Annotations. These annotations will help to easily declare a set of endpoints that display and create a collection of quotes. Annotations allow for a simplified configuration right alongside the code, instead of having to be declared in a separate configuration file. They also allow for better testability through integrations with JUnit and Mockito.

Labs

Path Info

Level
Clock icon Intermediate
Duration
Clock icon 50m
Published
Clock icon Apr 26, 2023

Contact sales

By filling out this form and clicking submit, you acknowledge our privacy policy.

Table of Contents

  1. Challenge

    Introduction

    Welcome to Part 1 of the lab series:

    Creating a Quotes REST API with Spring Boot 3.

    This series of labs will guide you through some of the basic concepts for creating a RESTful API Service using Spring Boot with the Spring Web dependency.

    In this lab, you will complete the configuration of the QuotesController class using Spring Web Annotations. These annotations will help to easily declare a set of endpoints that display and create a collection of quotes. Annotations allow for a simplified configuration right alongside the code, instead of having to be declared in a separate configuration file. They also allow for better testability through integrations with JUnit and Mockito.

    The base code to the right was easily bootstrapped using this Spring Initializr template. Thanks to this Spring Boot template, there is little infrastructure to code since it has automatically configured all of the required Spring Framework options for you. Instead, you can focus on the actions to be developed.

    The base methods of the QuotesController and QuotesService classes were also created to allow you to focus on the configuration annotations.

    To get started with this lab, click the Next step > button below.

  2. Challenge

    Create an Endpoint to Retrieve All Quotes

    The first step is to declare the QuotesController class and declare the first endpoint.

    As previously mentioned, Spring uses annotations to easily declare controllers and endpoint mappings.

    To declare the QuotesController class as a rest controller you can add the @RestController annotation right above the class declaration.
    such as:

    @RestController
    public class QuotesController {
    

    Now that the class has been declared as a @RestController the getQuotes method can be declared as a @RequestMapping This can be accomplished using the annotation:

    @RequestMapping(value="/",method = RequestMethod.GET)
    public List<String> getQuotes() { 
    

    Another option would be to use the shortcut annotation below:

    @GetMapping("/")
    public List<String> getQuotes() { 
    

    To test this first endpoint:
    First, open the left Terminal window and type the following command:

    gradle bootrun
    

    Then in the right Terminal window you can query this new API using the curl command:

    curl http://localhost:8888
    

    You should see a response of a JSON array of strings containing the quotes currently stored in the application.

    Note: The running server in the left Terminal will need to be restarted for each code change. To stop the server, open the left Terminal, click within the window to give it focus, and then type the keys Ctrl+C.

    When ready, click the Next step > button below.

    Some Points of Interest:
    The @RestController annotation is really a convenient annotation that wraps the @Controller and @ResponseBody annotations.

    • @Controller declares this class as a web controller, along with all the related functionality, and allows this class to be autodetected for hosting.
    • @ResponseBody declares that all return values are sent directly to the client instead of the default behavior of returning the MVC view to display.

    Also, thanks to Spring automatic configuration, these responses will be converted to JSON format by the default configuration for the HttpMessageConverter.

  3. Challenge

    Declare a Common Path For All Endpoints in Controller

    As seen in the previous step, this endpoint is currently being hosted under the application root. To help prepare this Quotes API to be part of a larger project, the requirement is to host this API under the path /api/quotes.

    This could be accomplished by declaring this path in each mapping, such as: @GetMapping("/api/quotes").

    But there is an easier solution by adding a @RequestMapping("/api/quotes") annotation to the top of the class.

    The class now looks like:

    @RestController
    @RequestMapping("/api/quotes")
    public class QuotesController {
    

    This change will impact the current getQuotes mapping. The current @GetMapping("/") was previously required for the getQuotes endpoint to work correctly, but now with the class level RequestMapping this annotation forces the need to supply a trailing slash. such as: http://localhost:8888/api/quotes/. To fix this you can refactor the GetMapping annotation by removing the path parameter.

    @GetMapping()
    public List<String> getQuotes() {
    

    Now this endpoint is accessible without the trailing slash: http://localhost:8888/api/quotes. To test this change, you will need to restart the server in the left Terminal.

    If the server is still running, you can stop it by changing focus to the left Terminal and typing Ctrl+C. Then restart the server using the command;

    gradle bootrun
    

    In the second Terminal window, you can query this new path using the curl command:

    curl http://localhost:8888/api/quotes
    

    You should see the same json array previously seen.

    When ready, click the Next step > button below.

  4. Challenge

    Declare a Get Endpoint That Accepts a `PathVariable`

    Retrieving a collection of all content is a good start, but a RESTful API also allows for the retrieval of a single item from that collection.

    Typically this is presented in the API as an identifier following the collection endpoint. For instance, the Quotes API could retrieve a single quote by passing the list index number in the url. such as: /api/quotes/0.

    In this case, 0 is passed because the quotes are stored in a List, which is zero-based.

    To recognize this last item in the URL path as a variable, you will need to provide two annotations to the getQuoteByIndex method.

    The first annotation is to declare the RequestMapping of the method. This method, like the previous one, is a get http request, but this time declaring the last portion of the path as a variable.

    This is accomplished by placing the variable portion of the path within {}. for example @GetMapping("/{index}"), and then annotating the method's parameter as a @PathVariable.

    The getQuoteByIndex method should now look like:

    @GetMapping("/{index}") 
    public String getQuoteByIndex(@PathVariable int index) {
    

    By convention the path {index} is mapped to the method's index parameter because they are named the same. If they need to be different, this can be accomplished by passing the path name into the @PathVariable("index").

    In the left Terminal restart the server, and then in the right Terminal you can query this new endpoint by using the curl command:

    curl http://localhost:8888/api/quotes/0
    

    You should now see the specific quote at the requested index position. In this case, because the List is zero-based, pass a 0 for the first item. 

    Point of Interest:
    In addition to accepting a @PathVariable, an endpoint can also accept a @RequestParm (query string parameter) or a @RequestBody.

  5. Challenge

    Create a Post Endpoint that Adds a New Quote to the Collection

    Another useful feature of a RESTful API is the ability to add new content. This is accomplished by declaring an http POST request.

    Typically a POST request accepts an object in the body of the request.

    To declare a POST request, two sets of annotations need to be added to the addQuote method. This time using the @PostMapping() and @RequestBody on the method's parameter.
    The addQuote method should not look like:

    @PostMapping() 
    public void addQuote(@RequestBody String quote) { 
    

    Notice that the return of this method is currently void. For a production application you may want to return the actual instance of the object created, including an identifier that may have been created.

    Another consideration of a RESTful API is the response status returned to the client's request. For instance, the previous GET requests returned a status code of 200, which means that the server was able to successfully respond to the request.

    On the other hand, a POST request needs to respond with a status code of either 201, which means the server created the posted object, or 202, which means that the server has accepted and is processing the posted object.

    There are several ways to accomplish this in Spring Web. One of those is to add the @ResponseStatus annotation to the addQuote method.
    The method should now look like:

    @PostMapping() 
    @ResponseStatus(HttpStatus.CREATED)
    public void addQuote(@RequestBody String quote) { 
    

    Restart the server in the left Terminal, and execute the following command in the right Terminal window:

    curl -i -X POST http://localhost:8888/api/quotes -d "Add new quote here"
    

    Since the addQuote method is currently returning void, the -i option was added to the curl command to include the HTTP response headers. You should see the created status code HTTP/1.1 201.

  6. Challenge

    Next Steps

    Congratulations on completing Part 1 of this guided lab series on Spring!

    You are welcome to continue working with this lab to see what improvements you can make.

    Some ideas are to:

    • Create a PATCH request method that would update a quote at a particular index.
    • Create a DELETE request method that would delete a quote at a particular index.
    • For a bigger challenge, create a Quote class and refactor the project to use this Quote class instead of the String class.

    The best to you as you continue your learning journey here at Pluralsight. Hope to see you in Part 2 of this series.

Jeff Hopper is a polyglot solution developer with over 20 years of experience across several business domains. He has enjoyed many of those years focusing on the .Net stack.

What's a lab?

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Provided environment for hands-on practice

We will provide the credentials and environment necessary for you to practice right within your browser.

Guided walkthrough

Follow along with the author’s guided walkthrough and build something new in your provided environment!

Did you know?

On average, you retain 75% more of your learning if you get time for practice.