Call another rest api from my server in Spring-Boot

ApiSpring BootSpring DataRetrofit

Api Problem Overview


I want to call another web-api from my backend on a specific request of user. For example, I want to call Google FCM send message api to send a message to a specific user on an event.

Does Retrofit have any method to achieve this? If not, how I can do that?

Api Solutions


Solution 1 - Api

This website has some nice examples for using spring's RestTemplate. Here is a code example of how it can work to get a simple object:

private static void getEmployees()
{
    final String uri = "http://localhost:8080/springrestexample/employees.xml";
     
    RestTemplate restTemplate = new RestTemplate();
    String result = restTemplate.getForObject(uri, String.class);
     
    System.out.println(result);
}

Solution 2 - Api

Modern Spring 5+ answer using WebClient instead of RestTemplate.

Configure WebClient for a specific web-service or resource as a bean (additional properties can be configured).

@Bean
public WebClient localApiClient() {
    return WebClient.create("http://localhost:8080/api/v3");
}

Inject and use the bean from your service(s).

@Service
public class UserService {

    private static final Duration REQUEST_TIMEOUT = Duration.ofSeconds(3);

    private final WebClient localApiClient;

    @Autowired
    public UserService(WebClient localApiClient) {
        this.localApiClient = localApiClient;
    }

    public User getUser(long id) {
        return localApiClient
                .get()
                .uri("/users/" + id)
                .retrieve()
                .bodyToMono(User.class)
                .block(REQUEST_TIMEOUT);
    }

}

Solution 3 - Api

Instead of String you are trying to get custom POJO object details as output by calling another API/URI, try the this solution. I hope it will be clear and helpful for how to use RestTemplate also,

In Spring Boot, first we need to create Bean for RestTemplate under the @Configuration annotated class. You can even write a separate class and annotate with @Configuration like below.

@Configuration
public class RestTemplateConfig {

    @Bean
    public RestTemplate restTemplate(RestTemplateBuilder builder) {
       return builder.build();
    }
}

Then, you have to define RestTemplate with @Autowired or @Injected under your service/Controller, whereever you are trying to use RestTemplate. Use the below code,

@Autowired
private RestTemplate restTemplate;

Now, will see the part of how to call another api from my application using above created RestTemplate. For this we can use multiple methods like execute(), getForEntity(), getForObject() and etc. Here I am placing the code with example of execute(). I have even tried other two, I faced problem of converting returned LinkedHashMap into expected POJO object. The below, execute() method solved my problem.

ResponseEntity<List<POJO>> responseEntity = restTemplate.exchange(
    URL, 
    HttpMethod.GET, 
    null, 
    new ParameterizedTypeReference<List<POJO>>() {
    });
List<POJO> pojoObjList = responseEntity.getBody();

Happy Coding :)

Solution 4 - Api

Create Bean for Rest Template to auto wiring the Rest Template object.

@SpringBootApplication
public class ChatAppApplication {

	@Bean
	public RestTemplate getRestTemplate(){
		return new RestTemplate();
	}

	public static void main(String[] args) {
		SpringApplication.run(ChatAppApplication.class, args);
	}

}

Consume the GET/POST API by using RestTemplate - exchange() method. Below is for the post api which is defined in the controller.

@RequestMapping(value = "/postdata",method = RequestMethod.POST)
    public String PostData(){

       return "{\n" +
               "   \"value\":\"4\",\n" +
               "   \"name\":\"David\"\n" +
               "}";
    }

    @RequestMapping(value = "/post")
    public String getPostResponse(){
        HttpHeaders headers=new HttpHeaders();
        headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
        HttpEntity<String> entity=new HttpEntity<String>(headers);
        return restTemplate.exchange("http://localhost:8080/postdata",HttpMethod.POST,entity,String.class).getBody();
    }

Refer this tutorial[1]

[1] https://www.tutorialspoint.com/spring_boot/spring_boot_rest_template.htm

Solution 5 - Api

As has been mentioned in the various answers here, WebClient is now the recommended route. You can start by configuring a WebClient builder:

@Bean
public WebClient.Builder getWebClientBuilder(){
    return WebClient.builder();
}

Then inject the bean and you can consume an API as follows:

@Autowired
private WebClient.Builder webClientBuilder;


Product product = webClientBuilder.build()
            .get()
            .uri("http://localhost:8080/api/products")
            .retrieve()
            .bodyToMono(Product.class)
            .block();

Solution 6 - Api

>Does Retrofit have any method to achieve this? If not, how I can do that?

YES

Retrofit is type-safe REST client for Android and Java. Retrofit turns your HTTP API into a Java interface.

For more information refer the following link

https://howtodoinjava.com/retrofit2/retrofit2-beginner-tutorial

Solution 7 - Api

In this case need download whit my API, files hosted in other server.

In my case, don't need use a HTTP client to download the file in a external URL, I combined several answers and methods worked in previous code for files that were in my local server.

My code is:

@GetMapping(value = "/download/file/pdf/", produces = MediaType.APPLICATION_PDF_VALUE)
    public ResponseEntity<Resource> downloadFilePdf() throws IOException {
        String url = "http://www.orimi.com/pdf-test.pdf";
    
        RestTemplate restTemplate = new RestTemplate();
        byte[] byteContent = restTemplate.getForObject(url, String.class).getBytes(StandardCharsets.ISO_8859_1);
        InputStream resourceInputStream = new ByteArrayInputStream(byteContent);
    
        return ResponseEntity.ok()
                .header("Content-disposition", "attachment; filename=" + "pdf-with-my-API_pdf-test.pdf")
                .contentType(MediaType.parseMediaType("application/pdf;"))
                .contentLength(byteContent.length)
                .body(new InputStreamResource(resourceInputStream));
    }

and it works with HTTP and HTTPS urls!

Solution 8 - Api

Since the question explicitly tags spring-boot, it worth noting that recent versions already ship a pre-configured instance of a builder for WebClient, thus you can directly inject it inside your service constructor without the needing to define a custom bean.

@Service
public class ClientService {

    private final WebClient webClient;

    public ClientService(WebClient.Builder webClientBuilder) {
        webClient = webClientBuilder
						.baseUrl("https://your.api.com")
    }

    //Add all the API call methods you need leveraging webClient instance

}

https://docs.spring.io/spring-boot/docs/2.0.x/reference/html/boot-features-webclient.html

Solution 9 - Api

Simplest way I have found is to:

  • Create an annotated interface (or have it generated from somehing like OpenAPI)
  • Give that interface to Spring RestTemplate Client

The Spring RestTemplate Client will parse the annotations on the interface and give you a type safe client, a proxy-instance. Any invocation on the methods will be seamlessly translated to rest-calls.

final MyApiInterface myClient = SpringRestTemplateClientBuilder
  .create(MyApiInterface.class)
  .setUrl(this.getMockUrl())
  .setRestTemplate(restTemplate)         // Optional
  .setHeader("header-name", "the value") // Optional
  .setHeaders(HttpHeaders)               // Optional
  .build();

And a rest call is made by inoking methods, like:

final ResponseEntity<MyDTO> response = myClient.getMyDto();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMahdiView Question on Stackoverflow
Solution 1 - ApiTorsten N.View Answer on Stackoverflow
Solution 2 - ApiSnackoverflowView Answer on Stackoverflow
Solution 3 - ApiNallamachuView Answer on Stackoverflow
Solution 4 - ApiSenthuranView Answer on Stackoverflow
Solution 5 - ApiFredView Answer on Stackoverflow
Solution 6 - ApiMadhu TomyView Answer on Stackoverflow
Solution 7 - ApiJhonatan_CelisView Answer on Stackoverflow
Solution 8 - Api4javierView Answer on Stackoverflow
Solution 9 - ApiTomas BjerreView Answer on Stackoverflow