OpenFeign yerine kullanılır. Açıklaması şöyle
HTTP Interface Client introduced in Spring 6. The HTTP Interface Client enables to definition a declarative way for HTTP services using Java interfaces. Under the hood, Spring generates a proxy class that implements the interface and performs exchanges.
Bağımlılıklar
Açıklaması şöyle
All necessary components are in the spring-web module, that happens to be a transitive dependency for the spring-boot-starter-web or the spring-boot-starter-webflux modules. However, in practice the WebFlux dependency is always required at the moment due to the HttpServiceProxyFactory for generating the clients.
Açıklaması şöyle
Why do you need Spring Reactive Web dependenciesWhen creating the project above, the dependency of Spring Reactive Web was introduced, and the WebClient type was used when creating the service object of the proxy. This is because HTTP Interface currently only has built-in implementation of WebClient, which belongs to the category of Reactive Web. Spring will launch a RestTemplate-based implementation in subsequent versions.
Anotasyonlar
Anotasyonlar şöyle
@HttpExchange
@PutExchange
@DeleteExchange
baseUrl metodu
İsteğin gönderileceği URL adresini belirtir
Örnek
Şöyle yaparız
public interface CatFactsClient { @GetExchange(value = "/facts") List<Fact> getFacts(); } @Configuration public class CatFactsClientConfig { @Bean public CatFactsClient catFactsClient() { WebClient client = WebClient.builder() .baseUrl("https://cat-fact.herokuapp.com") .build(); HttpServiceProxyFactory factory = HttpServiceProxyFactory .builder(WebClientAdapter.forClient(client)) .build(); return factory.createClient(CatFactsClient.class); } } @Service public class MyService { @Autowired private CatFactsClient catFactsClient; public List<Fact> fetchCatFacts() { return catFactsClient.getFacts(); } }
clientConnector metodu
Örnek - WebClient Connection reset by peer error
Gönderilen istekler için keep-alive seçeneğini kapatmak gerekir. Şöyle yaparız
import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.support.WebClientAdapter; import org.springframework.web.service.invoker.HttpServiceProxyFactory; import reactor.netty.http.client.HttpClient; @Configuration public class HttpProxyConfiguration { @Value("${tracker.url}") private String trackerUrl; @Bean TrackerClient trackerClient(WebClient.Builder builder) { var httpClient = HttpClient.newConnection().keepAlive(false); // Here var reactorClientHttpConnector = new ReactorClientHttpConnector(httpClient); var wc = builder.baseUrl(trackerUrl) .clientConnector(reactorClientHttpConnector) .build(); var wca = WebClientAdapter.forClient(wc); return HttpServiceProxyFactory.builder() .clientAdapter(wca) .build() .createClient(TrackerClient.class); } }
defaultStatusHandler metodu
HttpStatus.NOT_FOUND, HttpStatusCode::is5xxServerError gibi durumlarda ne yapılacağını belirtir
Örnek
Elimizde şöyle bir kod olsun
@HttpExchange(url = "/characters",accept = MediaType.APPLICATION_JSON_VALUE)public interface CharacterClient {@GetExchangeList<CharacterResponse> getByName(@RequestParam String lastName);@GetExchange("/{id}")Optional<CharacterResponse> getById(@PathVariable long id);@PutExchange(contentType = MediaType.APPLICATION_JSON_VALUE)CharacterResponse addCharacter(@RequestBody AddCharacterRequest request);@DeleteExchange("/{id}")void deleteById(@PathVariable long id);}
Bu arayüzden Spring kod üretir. Daha sonra bu kodu WebClient ile birleştirmek gerekir. Şöyle yaparız
@Configuration public class CharacterClientConfig { @Bean public CharacterClient characterClient(CharacterClientProperties properties) { WebClient webClient = WebClient.builder() .baseUrl(properties.getUrl()) .defaultStatusHandler( httpStatusCode -> HttpStatus.NOT_FOUND == httpStatusCode, response -> Mono.empty()) .defaultStatusHandler( HttpStatusCode::is5xxServerError, response -> Mono .error(new ExternalCommunicationException(response.statusCode().value()))) .build(); return HttpServiceProxyFactory .builder(WebClientAdapter.forClient(webClient)) .build() .createClient(CharacterClient.class); } } @Data @Component @ConfigurationProperties("character-client") public class CharacterClientProperties { private String url; }
Açıklaması şöyle. Yani şimdilik HttpServiceProxyFactory + WebClientAdapter + WebClient kodunu elle yazmak gerekiyor.
Currently, unlike OpenFeign, the client is not yet supplied via auto-configuration in a Spring Boot setup (kindly track Support declarative HTTP clients #31337 for that matter). Therefore, we build a WebClient ourselves and create a declarative HTTP client from it by using the createClient method from HttpServiceProxyFactory. This is some kind of boilerplate code, but I am quite confident that the Spring Boot guys will come up with a nice solution to simplify this further. Up until this point, you will need such a bean definition for each declarative HTTP client in your application.
Kullanmak için şöyle yaparız
CharacterResponse brandon = characterClient .addCharacter(new AddCharacterRequest("Brandon", "Stark")); List<CharacterResponse> starks = characterClient.getByName("Stark"); Optional<CharacterResponse> eddardStark = characterClient.getById(1); Optional<CharacterResponse> unknown = characterClient.getById(1337L); // empty characterClient.deleteById(brandon.id());
Eğer Sadece Web Client Kullansaydık şöyle yaparız. Bu da karışık kodlar demek
public List<CharacterResponse> getByName(String lastName) { return webClient .get() .uri(uriBuilder -> uriBuilder .path("/characters") .queryParam("lastName", "{lastName}") .build(lastName)) .retrieve() .toEntityList(CharacterResponse.class) .block() .getBody(); }