24 Temmuz 2023 Pazartesi

SpringMVC RestClient Sınıfı - RestTemplate Gibidir

Giriş
Açıklaması şöyle. Yani reactive ve asenkron bir şey kullanmıyorsak ve RestTemplate'a göre daha basit bir şey istiyorsak RestClient kullanılabilir.
Spring framework has offered two different options to perform http requests:

1. RestTemplate: It was introduced in Spring 3 over a decade ago. It is an implementation of the Template pattern providing synchronous blocking communication.
2. WebClient: It was released in Spring 5 as part of Spring WebFlux library. It provides a fluent API and it follows a reactive model.
RestRemplate approach exposed too many HTTP features leading to a big number of overloaded methods. It employs the one thread per request paradigm from the Jakarta Servlet API.

WebClient is the replacement for RestTemplate supporting both synchronous and asynchronous calls. It is part of the Spring Web Reactive project.

Now Spring 6.1 M1 version presents RestClient. A new synchronous http client which works in a similar way to WebClient, using the same infrastructure as RestTemplate.
constructor
Şöyle yaparız
private String encodeBasic(String username, String password) {
    return "Basic "+Base64
        .getEncoder()
        .encodeToString((username+":"+password).getBytes());
}

RestClient restClient = RestClient.builder()
    .baseUrl(properties.getUrl())
    .defaultHeader(HttpHeaders.AUTHORIZATION,
        encodeBasic(properties.getUsername(), 
                    properties.getPassword())
    ).build();
delete metodu
Örnek
Şöyle yaparız
ResponseEntity<Void> response = restClient.delete()
  .uri("/{id}",2)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .toBodilessEntity();

logger.info("Deleted with status " + response.getStatusCode());
get metodu
Açıklaması şöyle
RestClient can also convert a response body in JSON format. Spring will automatically register by default MappingJackson2HttpMessageConverter or MappingJacksonHttpMessageConverter if Jackson 2 library or Jackson library are detected in the classpath. But you can register your own message converters and override the default settings.
Örnek
Şöyle yaparız
String data = restClient.get()
  .uri("?status={STATUS}&vip={vip}","activated", true)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .body(String.class);

logger.info(data);

CustomerResponse customer = restClient.get()
  .uri("/{id}",3)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .body(CustomerResponse.class);

logger.info("Customer name: " + customer.personInfo().name());

List<CustomerResponse> customers = restClient.get()
  .uri("?status={STATUS}&vip={vip}","activated", true)    
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .body(List.class);

logger.info("Customers size " + customers.size());
exchange metodu
Açıklaması şöyle
The exchange method is useful for situations where the response must be decoded differently depending on the response status. Status handlers are ignored when the exchange method is employed.
Örnek
Şöyle yaparız
SimpleResponse simpleResponse = restClient.get()
  .uri("/{id}",4)
  .accept(MediaType.APPLICATION_JSON)
  .exchange((req,res) -> 
    switch (res.getStatusCode().value()) {
      case 200 -> SimpleResponse.FOUND;
      case 404 -> SimpleResponse.NOT_FOUND;
      default -> SimpleResponse.ERROR;
    }
);
post metodu
Örnek
Şöyle yaparız
ResponseEntity<Void> response = restClient.post()
                .accept(MediaType.APPLICATION_JSON)
                .body(customer)
                .retrieve()
                .toBodilessEntity();

if (response.getStatusCode().is2xxSuccessful()) {
  logger.info("Created " + response.getStatusCode());
  logger.info("New URL " + response.getHeaders().getLocation());
}
Handling Errors
Açıklaması şöyle
What happens if we try to delete or retrieve a non-existing customer? The customer endpoint will return a 404 error code along with a message details. However, RestClient will throw a subclass of RestClientException whenever a client error status (400-499) or server error status (500-599) are received.

To define our custom exception handlers there are two options that work at different levels:

1. In the RestClient with defaultStatusHandler method (for all http request sent with it)
2. For each http request with the onstatus method after the call to retreive method (this method returns a ResponseSpec interface).
defaultStatusHandler metodu
Örnek
Şöyle yaparız
RestClient restClient = RestClient.builder()
  .baseUrl(properties.getUrl())
  .defaultHeader(HttpHeaders.AUTHORIZATION,
                 encodeBasic(properties.getUsername(), 
                 properties.getPassword()))
  .defaultStatusHandler(
    HttpStatusCode::is4xxClientError,
    (request, response) -> {
      logger.error("Client Error Status " + 
      response.getStatusCode());
      logger.error("Client Error Body "+new 
      String(response.getBody().readAllBytes()));
  })
.build();
onStatus metodu
Örnek
Şöyle yaparız
ResponseEntity response = restClient.delete()
  .uri("/{id}",2)
  .accept(MediaType.APPLICATION_JSON)
  .retrieve()
  .onStatus(HttpStatusCode::is4xxClientError,
    (req, res) -> 
    logger.error("Couldn't delete "+res.getStatusText())
  )
  .toBodilessEntity();

  if (response.getStatusCode().is2xxSuccessful())
    logger.info("Deleted with status " + response.getStatusCode());



Hiç yorum yok:

Yorum Gönder