- Lab
- Core Tech

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.

Path Info
Table of Contents
-
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.
-
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
thegetQuotes
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.
-
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 thegetQuotes
endpoint to work correctly, but now with the class levelRequestMapping
this annotation forces the need to supply a trailing slash. such as:http://localhost:8888/api/quotes/
. To fix this you can refactor theGetMapping
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.
-
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 aList
, 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'sindex
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 a0
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. -
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.
TheaddQuote
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 theaddQuote
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 returningvoid
, the-i
option was added to thecurl
command to include the HTTP response headers. You should see the created status codeHTTP/1.1 201
. -
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.
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.