Spring Boot REST API Example

By Arvind Rai, November 24, 2023
On this page, we will learn to create REST web service application in Spring Boot application. REST is REpresentational State Transfer. REST or RESTful web service provides communication medium between software applications on the Internet. REST uses uniform and predefined set of stateless operations. REST API can produce and consume JSON, XML and other media types. To create a Spring REST endpoint, we need to create a Spring controller annotated with @RestController. Spring provides @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping annotations to bind the request path with Spring controller methods. For CORS support, spring provides @CrossOrigin annotation that can be annotated at class level as well as method level. In Spring Boot application, to enable REST we need to include spring-boot-starter-web in our build files. It configures Jackson JSON library i.e. jackson-databind by default. Spring Boot REST produces JSON response when it detects Jackson JSON library in classpath and if it detects Jackson XML library then it produces XML response. For Jackson XML library we need to include jackson-dataformat-xml in our build files. Spring provides RestTemplate class to create REST client application. Here on this page we will create Spring REST CRUD example using CrudRepository and MySQL with complete detail step by step.

1. Maven Dependency

To work with Spring Boot REST API, we need to provide spring-boot-starter-web Maven dependency as following.
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency> 
The above Maven dependency by default collects the Jackson JSON library i.e. jackson-databind for JSON response.
To support XML response in Spring Boot REST, we need to provide jackson-dataformat-xml library with spring-boot-starter-web. Find the Maven dependency.
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.9.4</version>
</dependency> 
Include the above dependency in pom.xml and we are all set to get XML response.

2. URLs and Response Status Code for CRUD Operation

We will use following HTTP URLs, HTTP methods and response status code in our REST API example.
HTTP MethodURLStatus Code
CreatePOST/user/article201 CREATED, 409 CONFLICT
ReadGET/user/article/{id}200 OK
UpdatePUT/user/article200 OK
DeleteDELETE/user/article/{id}204 NO CONTENT


Find the print screen of the JSON response of our REST API example.
Spring Boot REST Example

3. REST Web Service Endpoint

To create a REST endpoint, we need to create a Spring controller annotated with @RestController . Here we have created endpoints for CRUD operations. We have created different web service methods to handle create, read, update and delete operations as given below.
ArticleController.java
@RestController
@RequestMapping("user")
@CrossOrigin(origins = {"http://localhost:4200"})
public class ArticleController {
	@Autowired
	private IArticleService articleService;
	
	//Fetches article by id
	@GetMapping("article/{id}")
	public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
		ArticleInfo ob = new ArticleInfo();
		BeanUtils.copyProperties(articleService.getArticleById(id), ob);
		return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
	}
	
	//Fetches all articles 
	@GetMapping(value="articles")
	public ResponseEntity<List<ArticleInfo>> getAllArticles() {
		List<ArticleInfo> responseArticleList = new ArrayList<>();
		List<Article> articleList = articleService.getAllArticles();
		for (int i = 0; i < articleList.size(); i++) {
			ArticleInfo ob = new ArticleInfo();
		    BeanUtils.copyProperties(articleList.get(i), ob);
		    responseArticleList.add(ob);    
		}
		return new ResponseEntity<List<ArticleInfo>>(responseArticleList, HttpStatus.OK);
	}
	
	//Creates a new article
	@PostMapping("article")
	public ResponseEntity<Void> addArticle(@RequestBody ArticleInfo articleInfo, UriComponentsBuilder builder) {
		Article article = new Article();
		BeanUtils.copyProperties(articleInfo, article);
                boolean flag = articleService.addArticle(article);
                if (flag == false) {
        	   return new ResponseEntity<Void>(HttpStatus.CONFLICT);
                }
                HttpHeaders headers = new HttpHeaders();
                headers.setLocation(builder.path("/article/{id}").buildAndExpand(article.getArticleId()).toUri());
                return new ResponseEntity<Void>(headers, HttpStatus.CREATED);
	}
	
	//Updates article
	@PutMapping("article")
	public ResponseEntity<ArticleInfo> updateArticle(@RequestBody ArticleInfo articleInfo) {
		Article article = new Article();
		BeanUtils.copyProperties(articleInfo, article);		
		articleService.updateArticle(article);
		
		ArticleInfo ob = new ArticleInfo();
		BeanUtils.copyProperties(article, ob);
		return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
	}
	
	//Deletes article by id
	@DeleteMapping("article/{id}")
	public ResponseEntity<Void> deleteArticle(@PathVariable("id") Integer id) {
		articleService.deleteArticle(id);
		return new ResponseEntity<Void>(HttpStatus.NO_CONTENT);
	}	
} 
@RestController: Used at class level to make REST endpoints. @RestController is combination of @Controller and @ResponseBody.
@CrossOrigin: Used for CORS support that permits cross-origin requests on class level as well as method level.
@RequestMapping: Maps web requests onto methods in REST web service endpoints to provide flexible method signature.

@GetMapping: Mapping with HTTP GET method.
@PostMapping: Mapping with HTTP POST method.
@PutMapping: Mapping with HTTP PUT method.
@DeleteMapping: Mapping with HTTP DELETE method.
@PatchMapping: Mapping with HTTP PATCH method.

@PathVariable: Indicates that a method parameter should be bound to a URI template variable.
@RequestBody: Used with the method parameter to bind the body of the web request.
@RequestParam: Used with method parameter to bind the web request parameter.

ResponseEntity: Extension of HttpEntity that represents HTTP request or response entity, consisting of headers and body.
UriComponentsBuilder: Builder for UriComponents that represents an immutable collection of URI components.

The annotations @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping are having optional elements as following.
consumes: Defines an array of consumable media types of mapped request.
produces: Defines an array of producible media types of mapped request.
headers: Defines the acceptable headers of mapped request.
params: Defines the parameters of the mapped request, narrowing the primary mapping.
path: Defines path mapping URIs in servlet environment.
name: Assigns a name to this mapping.
value: It defines primary mapping expressed by this annotation.

4. REST Web Service Client with RestTemplate

RestTemplate is the central class for synchronous client side HTTP access. RestTemplate communicates to REST using HTTP methods. Find some of RestTemplate methods.

getForObject: Retrieves data by using HTTP GET on specified URL.
postForLocation: Creates a new resource using given object to the URI template with HTTP POST method.
put: Creates or updates resource using given object to the URI template with HTTP PUT method.
delete: Deletes the resources at the specified URI.
exchange: Execute any HTTP method to the given URI template and returns ResponseEntity.

Find the sample example to execute RestTemplate.exchange method.
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);

String url = "http://localhost:8080/user/articles";

RestTemplate restTemplate = new RestTemplate();
HttpEntity<String> requestEntity = new HttpEntity<String>(headers);
ResponseEntity<Article[]> responseEntity = restTemplate.exchange(url, HttpMethod.GET, requestEntity, Article[].class); 
In the above code we are fetching all data of Article type using exchange with HTTP GET method. In our demo application, RestClientUtil.java contains client code.

5. Configure Producible and Consumable Media Types

A web service method can produce and consume primary media types by default. We can restrict to only configured media types to consume and produce. The annotations @RequestMapping, @GetMapping, @PostMapping, @PutMapping, @DeleteMapping and @PatchMapping are having optional elements as produces and consumes that is configured with required media types. Find the sample code.
@GetMapping(value= "article/{id}", produces= { MediaType.APPLICATION_XML_VALUE },
	consumes= { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
  ArticleInfo ob = new ArticleInfo();
  BeanUtils.copyProperties(articleService.getArticleById(id), ob);
  return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
} 
Now the above web service method can only produce application/xml and consume application/json media types.
If we want to configure media types at class level that will be applicable for all its web service methods, we can do it using @RequestMapping as following.
@RestController
@RequestMapping(value= "user", produces= { MediaType.APPLICATION_XML_VALUE },
    consumes= { MediaType.APPLICATION_JSON_VALUE })
public class ArticleController {
------
} 

6. JSON Response

Spring uses the Jackson JSON library to automatically marshal instances of type resource into JSON. Our Spring REST API application will produce JSON response by default if there is Jackson JSON library i.e. jackson-databind in the classpath. In Spring Boot application, the spring-boot-starter-web library by default includes jackson-databind library. To ignore null values in JSON response using Jackson JSON, we need to use @JsonInclude in our resource class.
ArticleInfo.java
public class ArticleInfo {
    @JsonInclude(Include.NON_NULL)
    private long articleId;

    @JsonInclude(Include.NON_NULL)
    private String title;

    @JsonInclude(Include.NON_NULL)
    private String category;

    //Getters and Setters
} 
Our web service methods can be restricted to produce only JSON response using produces element of mapping annotations such as @GetMapping.
@GetMapping(value= "article/{id}", produces= { MediaType.APPLICATION_JSON_VALUE })
public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
  ArticleInfo ob = new ArticleInfo();
  BeanUtils.copyProperties(articleService.getArticleById(id), ob);
  return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
} 
To configure HttpMessageConverter for JSON, we can create JavaConfig as following.
AppConfig.java
@Configuration 
@ComponentScan("com.concretepage") 
@EnableWebMvc   
public class AppConfig implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.indentOutput(true);
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    }
}

7. XML Response

To get XML response by our Spring REST API, we need to include Jackson XML library i.e. jackson-dataformat-xml library in our application classpath. Find the maven dependency for jackson-dataformat-xml library.
<dependency>
  <groupId>com.fasterxml.jackson.dataformat</groupId>
  <artifactId>jackson-dataformat-xml</artifactId>
  <version>2.9.4</version>
</dependency> 
We just need to include above Maven dependency in pom.xml and we are all set to get XML response. We can use @JacksonXmlProperty annotation in our resource class to change local name etc.
ArticleInfo.java
@JacksonXmlRootElement(localName="article", namespace="com.concretepage")
public class ArticleInfo {
    @JacksonXmlProperty(localName="articleId")
    private long articleId;

    @JacksonXmlProperty(localName="title")
    private String title;

    @JacksonXmlProperty(localName="category")
    private String category;

    //Getters and Setters
} 
Our web service methods can be restricted to produce only XML response using produces element of mapping annotations such as @GetMapping.
@GetMapping(value= "article/{id}", produces= { MediaType.APPLICATION_XML_VALUE })
public ResponseEntity<ArticleInfo> getArticleById(@PathVariable("id") Integer id) {
  ArticleInfo ob = new ArticleInfo();
  BeanUtils.copyProperties(articleService.getArticleById(id), ob);
  return new ResponseEntity<ArticleInfo>(ob, HttpStatus.OK);
} 
To configure HttpMessageConverter for XML, we can create JavaConfig as following.
AppConfig.java
@Configuration 
@ComponentScan("com.concretepage") 
@EnableWebMvc   
public class AppConfig extends WebMvcConfigurerAdapter {  
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = Jackson2ObjectMapperBuilder.xml();
        builder.indentOutput(true);
        converters.add(new MappingJackson2XmlHttpMessageConverter(builder.build()));
    }	
} 

8. CORS Support

For CORS support, Spring provides @CrossOrigin annotation. This annotation can be used at class level as well as method level in RESTful Web service controller. Find the sample code to use it at class level.
@RestController
@RequestMapping("user")
@CrossOrigin(origins = {"http://localhost:4200"})
public class ArticleController {
------
} 
In the above code we have configured origin for CORS support as http://localhost:4200 . It means a web application running at URL http://localhost:4200 can only access our REST API application.

9. Reference

Spring Boot Reference Guide

10. Download Source Code

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE








©2024 concretepage.com | Privacy Policy | Contact Us