the simplest way to call to REST api with Springboot

In this tutorial, we’ll demonstrate how easy it is to create a REST client with Spring boot to consume a REST api endpoint using declarative style

First, let’s create REST service using nodejs following the example here: https://leftsidemonitor.com/nodejs-express-create-project/

router.get('/api/users', function(req, res, next) {
  let users = [{
    'name': 'Hulk',
    'skill': 'Smash'
  }, {
    'name': 'Thor',
    'skill': 'thunder'
  }];

  res.end(JSON.stringify(users));
});

Let’s test this microservice:

curl http://localhost:3000/api/users
[
  {
    "name": "Hulk",
    "skill": "Smash"
  },
  {
    "name": "Thor",
    "skill": "thunder"
  }
]

Now in your Spring boot project, let’s define a model that is corresponded to the above data model

package com.leftsidemonitor.testhero.model;

import lombok.Data;

@Data
public class User {
    private String name;
    private String skill;
}

Before we go ahead and create a REST client, the following packages are needed, please update your pom.xml if you’re using maven

## Add to pom.xml
<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-httpclient</artifactId>
  <version>11.0</version>
</dependency>
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-jackson</artifactId>
  <version>11.0</version>
</dependency>
<dependency>
  <groupId>io.github.openfeign</groupId>
  <artifactId>feign-slf4j</artifactId>
  <version>11.0</version>
</dependency>

<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.testcontainers</groupId>
      <artifactId>testcontainers-bom</artifactId>
      <version>${testcontainers.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
    <dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-dependencies</artifactId>
      <version>Hoxton.SR6</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

Now is a simple REST client using Spring Cloud Feign library

package com.leftsidemonitor.testhero.client;

import com.leftsidemonitor.testhero.model.User;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;

import java.util.List;

@FeignClient(name = "users", url = "${remote.api.user.client}")
public interface UserServiceClient {
    @GetMapping(value = "/users", produces = MediaType.APPLICATION_JSON_VALUE)
    List<User> getUsers();
}

Now let’s create a simple Service class that uses this REST client and also modify the receiving data:

package com.leftsidemonitor.testhero.service;

import com.leftsidemonitor.testhero.client.UserServiceClient;
import com.leftsidemonitor.testhero.model.User;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@AllArgsConstructor
public class UserService {
    private UserServiceClient userServiceClient;

    public List<User> getUsersFromRemoteAPI() {
        List<User> remoteUsers = userServiceClient.getUsers();
        return remoteUsers.stream()
                .peek(user -> user.setName("From a galaxy far away: " + user.getName()))
                .collect(Collectors.toList());
    }
}

And here is a controller class to bind all of these together

package com.leftsidemonitor.testhero.web;

import com.leftsidemonitor.testhero.model.User;
import com.leftsidemonitor.testhero.service.UserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/remote")
@Slf4j
@AllArgsConstructor
public class UserResource {
    private UserService userService;

    @GetMapping("/users")
    public List<User> getRemoteUsers() {
        return userService.getUsersFromRemoteAPI();
    }
}

Important: in order for FeignClient to work, there must be a simple configuration as following:

package com.leftsidemonitor.testhero.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import feign.Logger;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.jackson.JacksonDecoder;
import feign.jackson.JacksonEncoder;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableFeignClients(basePackages = "com.leftsidemonitor.testhero.client")
public class FeignConfig {
    private static final ObjectMapper mapper = new ObjectMapper();

    private final ObjectFactory<HttpMessageConverters> messageConverters;

    public FeignConfig(ObjectFactory<HttpMessageConverters> messageConverters) {
        this.messageConverters = messageConverters;
    }

    @Bean
    public Decoder feignDecoder() {
        return new JacksonDecoder(mapper);
    }

    @Bean
    public Encoder feignEncoder() {
        return new JacksonEncoder(mapper);
    }

    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.BASIC;
    }
}
remote.api.user.client=http://localhost:3000/api

Now let’s test:

curl http://localhost:8080/remote/users
[
  {
    "name": "From a galaxy far away: Hulk",
    "skill": "Smash"
  },
  {
    "name": "From a galaxy far away: Thor",
    "skill": "thunder"
  }
]
Add to my src(0)

No account yet? Register

Set Spring Profile with Maven command line as a parameter

Spring and spring-boot can be run from the IDE, and the profile can be parse via environment variable, and sometimes it’s quick to use maven parameter

mvn -Pspring.profiles.active=development spring-boot:run
## If running with java command.
java -Dspring.profiles.active=development -jar yourApp.jar
Add to my src(0)

No account yet? Register