Spring Boot REST API example
REST is an acronym for REpresentational State Transfer. In this article, we will walk through a sample REST application built using Spring Boot. This application does not use any database to store data, all the data is in memory. We will expose a few REST endpoints. Main purpose of this article is to demonstrate how to build REST API's using Spring boot.
Application Details
This application is about building a backend for a Blog software and exposing two REST API endpoints.
Following two endpoints both returns response in JSON format.
/blogapi/blogs : Returns list of blogs
/blogapi/blogs/ID : Returns details of a specific blog
Following two endpoints both returns response in JSON format.
/blogapi/blogs : Returns list of blogs
/blogapi/blogs/ID : Returns details of a specific blog
Technology Used
- Spring Boot 2.2.6.RELEASE
- Logback 1.2.3
- Maven 3
- Java 11
- Jackson 2.10.3
Project Structure
Code Reference
Maven pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>com.bootng.rest</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Spring Boot Rest</name>
<description>Springboot Rest App</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
<!-- junit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>2.19.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<addResources>true</addResources>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
BlogStory Model
BlogStory model class which represent a blog entry.
package com.bootng.model;
public class BlogStory {
private String id;
private String name;
private String summary;
private String description;
private String category;
public BlogStory() {
}
public BlogStory (String name, String category, String summary) {
this.id = name.replaceAll(" ","_");
this.name = name;
this.summary = summary;
this.category = category;
this.description = summary + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt "
+ "ut labore et dolore magna aliqua. "
+ "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
+ " Duis aute irure dolor in reprehenderit in voluptate velit esse cillum "
+ "dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, "
+ "sunt in culpa qui officia deserunt mollit anim id est laborum" ;
}
// Setters
}
BlogService Class
Service class which returns list of available blogs. Blog with an id etc.
@Service
public class BlogService {
List category = Arrays.asList("Technical", "Travel", "Food", "Finance", "Entertainment");
List stories = new ArrayList();
{
stories.add(new BlogStory("Java 11", "Technical", "Java 11 Blog"));
stories.add(new BlogStory("Java 14", "Technical", "Java 14 Blog"));
stories.add(new BlogStory("Asia Travel", "Travel", "Places to visit in Asia"));
stories.add(new BlogStory("Europe Travel", "Travel", "Places to visit in Europe"));
stories.add(new BlogStory("Japan Travel", "Travel", "Places to visit in Japan"));
stories.add(new BlogStory("Asian Food", "Food", "Asian Food......"));
}
public BlogStory getBlogStory(String id) throws AppException {
return stories.stream().filter(story -> id.equals(story.getId())).findAny().orElse(null);
}
public List getBlogStory() throws AppException {
return stories;
}
public void addStory(BlogStory newStory) throws AppException {
this.stories.add(newStory);
}
public List getBlogTags() throws AppException {
return category;
}
}
Main Application Class
Spring Boot's main application class.
@ComponentScan({"com.bootng"})
@SpringBootApplication
public class RestApplication {
public static void main(String args[]) {
SpringApplication.run(RestApplication.class, args);
}
}
BlogAPIController Controller Class
Controller class which exposes the two endpoints
GET /blogapi/blogs
and GET /blogapi/blogs/ID
@Controller annotation is used to mark this class as a Controller.
@RequestMapping is used to map the request paths "/blogs" to getBlogSotries method and /blog/ID to getBlogStory method.
In both cases we are mapping both the paths to HTTP GET verb by using method = RequestMethod.GET
@ResponseBody is used to convert the result to JSON (as we specified by produces=MediaType.APPLICATION_JSON_VALUE)
GET /blogapi/blogs
and GET /blogapi/blogs/ID
@Controller annotation is used to mark this class as a Controller.
@RequestMapping is used to map the request paths "/blogs" to getBlogSotries method and /blog/ID to getBlogStory method.
In both cases we are mapping both the paths to HTTP GET verb by using method = RequestMethod.GET
@ResponseBody is used to convert the result to JSON (as we specified by produces=MediaType.APPLICATION_JSON_VALUE)
@Controller
@RequestMapping("/blogapi")
public class BlogAPIController {
private static final Logger log = LoggerFactory.getLogger(BlogAPIController.class);
@Autowired
BlogService blogService;
ResponseEntity apiResponse = new ResponseEntity(newStory, HttpStatus.OK);
return apiResponse;
}
@RequestMapping(value = {"/blogs"}, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity> getBlogStories() {
log.info("inside getBlogStories GET method");
List blogStory = null;
ResponseEntity> apiResponse;
try {
blogStory = blogService.getBlogStory();
apiResponse = new ResponseEntity>(blogStory, HttpStatus.OK);
} catch (AppException e) {
apiResponse =
new ResponseEntity>(blogStory, HttpStatus.INTERNAL_SERVER_ERROR);
e.printStackTrace();
}
return apiResponse;
}
@RequestMapping(value = {"/blogs"}, method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
public @ResponseBody ResponseEntity getBlogStory(@PathParam(value = "") String id) {
log.info("inside blog GET method");
BlogStory blogStory = null;
ResponseEntity apiResponse;
try {
blogStory = blogService.getBlogStory(id);
if (blogStory == null)
apiResponse = new ResponseEntity(blogStory, HttpStatus.NOT_FOUND);
else
apiResponse = new ResponseEntity(blogStory, HttpStatus.OK);
} catch (AppException e) {
apiResponse = new ResponseEntity(blogStory, HttpStatus.INTERNAL_SERVER_ERROR);
e.printStackTrace();
}
return apiResponse;
}
}
Start Application
Run Application
Build the project using mvn clean install and then run it with mvn spring-boot:run
mvn clean install
mvn spring-boot:run
Call REST API's using CURL
CURL: Get list of Blogs
Using curl we can get list of blogs from the /blogs endpoint
curl -X GET http://localhost:8080/blogapi/blogs
CURL: Get specific blog details
Get a specific blog with id "Java_14" by calling /blogs/Java_14
curl -X GET localhost:8080/blogapi/blogs/Java_14
Git Source Code
- git clone https://github.com/siddharthagit/spring-boot-references
- cd springboot-rest
- mvn clean install
- mvn spring-boot:run
Conclusion
In this article, we used Springs RestController annotation to build the API.
With Spring boot we can use other frameworks like Jersey, Restlet, etc also to build API.