【SFA官方翻译】:Micronaut Mastery:HTTP客户端的特定配置属性使用
原文链接:https://dzone.com/articles/micronaut-mastery-using-specific-configuration-pro
作者:Hubert Klein Ikkink
译者:Emma
学习如何在微服务应用程序中使用Micronaut和Java注入简单的HTTP客户端。
Micronaut的(许多)强大功能之一是HTTP客户端。我们使用@Client注解注入一个低级HTTP客户端。或者我们基于接口定义声明性HTTP客户端,Micronaut将为其生成实现。@Client注解支持配置参数,以引用具有HTTP客户端配置属性的配置类。配置类扩展了HttpClientConfiguration以支持例如超时和连接池的配置。我们也可以添加自己的配置属性,并在我们的应用程序中使用它们。
在下面的示例中,我们使用声明性HTTP客户端访问OpenWeatherMap API。首先,我们编写一个扩展HttpClientConfiguration的类。这个类为我们提供了HTTP客户端配置属性,我们还添加了一些属性来定义调用REST API所需的OpenWeatherMap URI,路径和访问密钥。最后,我们为想要用于HTTP客户端的配置属性添加@Retryable注解。
// File: src/main/java/mrhaki/micronaut/WeatherClientConfiguration.java
package weather;
import io.micronaut.context.annotation.ConfigurationProperties;
import io.micronaut.http.client.HttpClientConfiguration;
import io.micronaut.runtime.ApplicationConfiguration;
import java.net.URI;
import java.time.Duration;
import static weather.WeatherClientConfiguration.PREFIX;
/**
* Custom HTTP client configuration set via application
* properties prefixed with "weather.client".
*/
@ConfigurationProperties(PREFIX)
public class WeatherClientConfiguration extends HttpClientConfiguration {
public static final String PREFIX = "weather.client";
/**
* HTTP client connection pool configuration.
*/
private final WeatherClientConnectionPoolConfiguration connectionPoolConfiguration;
/**
* OpenWeatherMap URI.
*/
private URI url;
/**
* Path for requests sent to OpenWeatherMap.
*/
private String path;
/**
* Key needed to access OpenWeatherMap API.
*/
private String apiKey;
public WeatherClientConfiguration(
final ApplicationConfiguration applicationConfiguration,
final WeatherClientConnectionPoolConfiguration connectionPoolConfiguration) {
super(applicationConfiguration);
this.connectionPoolConfiguration = connectionPoolConfiguration;
}
public URI getUrl() {
return url;
}
public void setUrl(final URI url) {
this.url = url;
}
public String getPath() {
return path;
}
public void setPath(final String path) {
this.path = path;
}
public String getApiKey() {
return apiKey;
}
public void setApiKey(final String apiKey) {
this.apiKey = apiKey;
}
@Override
public ConnectionPoolConfiguration getConnectionPoolConfiguration() {
return connectionPoolConfiguration;
}
@ConfigurationProperties(ConnectionPoolConfiguration.PREFIX)
public static class WeatherClientConnectionPoolConfiguration extends ConnectionPoolConfiguration {
}
/**
* Extra configuration propertie to set the values
* for the @Retryable annotation on the WeatherClient.
*/
@ConfigurationProperties(WeatherClientRetryConfiguration.PREFIX)
public static class WeatherClientRetryConfiguration {
public static final String PREFIX = "retry";
private Duration delay;
private int attempts;
public Duration getDelay() {
return delay;
}
public void setDelay(final Duration delay) {
this.delay = delay;
}
public int getAttempts() {
return attempts;
}
public void setAttempts(final int attempts) {
this.attempts = attempts;
}
}
}
接下来,我们使用@Client注解编写声明性HTTP客户端作为Java接口。我们引用自定义配置并使用配置属性来设置访问OpenWeatherMap API的URI和路径。
// File: src/main/java/mrhaki/micronaut/WeatherClient.java
package weather;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.client.Client;
import io.micronaut.retry.annotation.Retryable;
import io.reactivex.Single;
import java.util.Map;
// Declarative HTTP client with URL and path
// fetched from the application configuration.
// HTTP client configuration like pooled connections,
// timeouts are defined using WeatherClientConfiguration.
@Client(
value = "${weather.client.url}",
path = "${weather.client.path}",
configuration = WeatherClientConfiguration.class)
// Retry accessing OpenWeatherMap REST API if error occurs.
@Retryable(
attempts = "${weather.client.retry.attempts}",
delay = "${weather.client.retry.delay}")
interface WeatherClient {
/**
* Get weather description for the town of Tilburg, NL.
* The APPID query parameter is filled in with the apiKey
* argument value.
*
* @param apikey OpenWeatherMap API key to access REST API.
* @return Response data from REST API.
*/
@Get("weather?q=Tilburg,nl&APPID={apikey}")
Single<Map<String, Object>> tilburg(String apikey);
}
最后,我们编写了一个控制器,它使用声明性HTTP客户端WeatherClient来获取荷兰蒂尔堡镇的天气描述:
// File: src/main/java/mrhaki/micronaut/WeatherController.java
package weather;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.reactivex.Single;
import java.util.List;
import java.util.Map;
/**
* Controller to expose data from the
* OpenWeatherMap REST API.
*/
@Controller("/weather")
public class WeatherController {
private final WeatherClient client;
private final WeatherClientConfiguration configuration;
public WeatherController(
final WeatherClient client,
final WeatherClientConfiguration configuration) {
this.client = client;
this.configuration = configuration;
}
/**
* Get weather data for town Tilburg, NL and get the
* weather description to return.
*
* @return Weather description as text.
*/
@Get(value = "/tilburg", produces = MediaType.TEXT_PLAIN)
public Single<String> weatherInTilburg() {
return client.tilburg(configuration.getApiKey())
.map(response -> getWeatherDescription(response));
}
/**
* Get weather description from response data.
*
* @param data Response data from OpenWeatherMap API.
* @return Textual description of weather.
*/
private String getWeatherDescription(final Map<String, Object> data) {
final List<Object> weatherList = (List<Object>) data.get("weather");
final Map<String, Object> weather = (Map<String, Object>) weatherList.get(0);
final String description = (String) weather.get("description");
return description;
}
}
在application.yml配置文件中,我们设置配置属性的值:
# File: src/main/resources/application.yml
...
weather:
client:
url: http://api.openweathermap.org/
path: /data/2.5/
api-key: 39caa...
read-timeout: 500ms
retry:
attempts: 2
delay: 5s
当我们运行我们的应用程序并使用HTTPie访问URL http:// localhost:8080 / weather / tilburg时,我们会得到天气描述:
$ http :8080/weather/tilburg
HTTP/1.1 200 OK
Content-Length: 13
Content-Type: text/plain;charset=UTF-8
moderate rain
用Micronaut 1.0.0.M4编写。