Anomalyzero
Anomalyzero

Reputation: 125

Spring RestTemplate: How to repeatedly check Restful API Service?

I am attempting to create a SpringBoot application that will consume data from a 3rd party REST API and push Websocket notifications to my own clients based on events/changes to that data. The data I am consuming changes frequently, sometimes dozens of times a second (crypto currency price fluctuations behave similarly to this data). I want to repeatedly call the API on a fixed interval (every 1-10 seconds for example), watch for certain events/changes and trigger a Websocket push when those events occur.

I've been able to build a simple Spring Boot app that can push Websocket Notifications and consume the API by following these guides:

The Problem: I can only get the Application to request the data from the API once. I've spent hours searching every variation of "Spring RestTemplate multiple/repeated/persistent calls" I can think of, but I cannot find a solution that addresses my specific use. The closest examples I've found use retries but even those will eventually give up. I want my application to continually request this data until I shut the application down. I know I could wrap it in a while(true) statement or something like that, but that really doesn't seem right for a framework like SpringBoot and still has problems when trying to instantiate the RestTemplate.

How can I implement persistent querying of a RESTful API resource?

Below is what I have in my Application class

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@EnableScheduling
public class Application {

    private static final String API_URL = "http://hostname.com/api/v1/endpoint";

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

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

    @Bean
    public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
        return args -> {
            Response response= restTemplate.getForObject(API_URL, Response.class);
            System.out.println(response.toString());
        };
    }
}

Upvotes: 4

Views: 5405

Answers (2)

Siddharth Sachdeva
Siddharth Sachdeva

Reputation: 1906

Add @EnableScheduling annotation on your SpringConfig class or Main class.

You can use Scheduled fixedDelay OR fixedRate

@Scheduled(fixedDelay = 10000)
    public void test() {
        System.out.println("Scheduler called.");
    }

OR

@Scheduled(fixedRate  = 10000)
    public void test() {
        System.out.println("Scheduler called.");
    }

Difference between fixedDelay and fixedRate:

fixedDelay - makes sure that there is a delay of n millisecond between the finish time of an execution of a task and the start time of the next execution of the task.

fixedRate - runs the scheduled task at every n milliseconds.

Ideally, you should externalise the fixedDelay or fixedRate value as well in application.properties file:

@Scheduled(fixedDelayString  = "${scheduler.fixed.delay}")
    public void test() {
        System.out.println("Scheduler called.");
    }

In your application.properties file add below config:

scheduler.fixed.delay = 10000

Hope this helps.

Upvotes: 1

aarbor
aarbor

Reputation: 1534

CommandLineRunner only runs once per application start. Instead, you want to use the @Scheduled annotation to perform repeated operations at fixed intervals like

    @Scheduled(fixedDelay = 1000L)
    public void checkApi() {
        Response response = restTemplate.getForObject(API_URL, Response.class);
        System.out.println(response.toString())
    }

It does not need to be a Bean, it can just be a simple method. See the Spring guide for more information https://spring.io/guides/gs/scheduling-tasks/

Upvotes: 4

Related Questions