Friday, August 3, 2018

How to use Rest Template with Spring Boot

This is very simple demonstration which shows how to use Rest Template with Spring Boot. In this example I will create Java APIs using Spring Boot to call another REST API to GET, POST and PATCH data.
To make it done, I'm using another REST application to work as a service. You can clone it using following git repository. This can be any application which creates REST APIs, may be Java, PHP, Python or whatever.
https://github.com/raviyasas/SpringBoot-REST-API-demo.git
This application will run on port 8090. Please read the ReadMe file for API details.
Now I am going to create another Spring Boot application to to call those APIs using Rest Template.

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>

    <groupId>com.app</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </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-data-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

User.java

package com.app.demo.model;

import lombok.Data;
import java.io.Serializable;

@Data
public class User implements Serializable {
    private String name;
    private String email;
}

ApiController.java

package com.app.demo.controller;

import com.app.demo.model.*;
import com.app.demo.service.ApiService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;

@RestController
@RequestMapping("/api/v2/users/")
public class ApiController {

    @Autowired
    private ApiService apiService;

    @GetMapping("/getData")
    public List<User> getData(){
        return apiService.getInfo();
    }

    @PostMapping("/postData")
    public User postData(@RequestBody User user){
        return apiService.saveData(user);
    }

    @PatchMapping("/patchData/{id}")
    public User getPatchData(@RequestBody User user, @PathVariable Long id){
        return apiService.patchData(user, id);
    }

    @DeleteMapping("/deleteData/{id}")
    public void deleteData(@PathVariable Long id){
        apiService.deleteData(id);
    }
}


ApiService.java

package com.app.demo.service;

import com.app.demo.model.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;

@Service
@Transactional
public class ApiService {

    @Autowired
    private RestTemplateBuilder restTemplateBuilder;

    public List<User> getInfo() {

        String url = "http://localhost:8090/api/user/users";

        ResponseEntity<List<User>> result = restTemplateBuilder.build().
                exchange(url,
                        HttpMethod.GET, null, new ParameterizedTypeReference<List<User>>() {});

        List<User> userList = new ArrayList<>();
        userList.addAll(result.getBody());

        return userList;
    }

    public User saveData(User requestUser) {

        String url = "http://localhost:8090/api/user/addUser";

        ResponseEntity<User> result = restTemplateBuilder.build().postForEntity(url, requestUser, User.class);

        User user = new User();
        user.setEmail(result.getBody().getEmail());
        user.setName(result.getBody().getName());

        return user;
    }

    public User patchData(User requestUser, Long id) {

        String url = "http://localhost:8090/api/user/patchUser/" + id;

        Object result = restTemplateBuilder.build().patchForObject(url, requestUser, User.class);

        User user = new User();

        if(result != null) {
            if (requestUser.getName() != null) {
                user.setName(((User) result).getName());
            }
            if (requestUser.getEmail() != null) {
                user.setEmail(((User) result).getEmail());
            }
        }
        return user;
    }

    public void deleteData(Long id) {

        String url = "http://localhost:8090/api/user/deleteUser/" + id;

        try{
            restTemplateBuilder.build().delete(url);
        }catch (Exception e){
            e.getMessage();
        }
    }
}

You can use following curl commands to GET, POST, PATCH and DELETE data. My application is running on port 8088, by default it will run on port 8080. You can change it by setting server.port=8088 in application.properties

Get user data

curl -XGET 'http://localhost:8088/api/v2/users/getData/'


Add new user

curl -XPOST -H "Content-type: application/json" -d '{
    "name": "testUser",
    "email": "testuser@live.com"
}' 'http://localhost:8088/api/v2/users/postData/' 


Update a user

curl -XPATCH -H "Content-type: application/json" -d '{
    "email": "newEmail@live.com"

}' 'http://localhost:8088/api/v2/users/patchData/2'


Remove a user

curl -XDELETE 'http://localhost:8088/api/v2/users/deleteData/2'


You can download the complete project from here.

https://github.com/raviyasas/SpringBoot-RestTemplate-demo.git