HTTP клиент
Модуль предоставляет тонкий слой абстракции для создания HTTP-клиентов с помощью аннотаций в декларативном стиле, либо использование клиентов в императивном стиле.
OkHttp¶
Реализация HTTP клиента основанная на библиотеке OkHttp. Учитывайте что реализация написана на Kotlin и использует соответствующие зависимости. Лучше всего подходит для Kotlin сервисов, либо Java сервисов где нужна высокая производительность, либо требуется поддержка HTTP 3, либо поддержка GZip сжатия, либо другие специфичные HTTP опции.
Подключение¶
Зависимость build.gradle
:
Модуль:
Зависимость build.gradle.kts
:
Модуль:
Конфигурация¶
Пример полной конфигурации, описанной в классе OkHttpClientConfig
и HttpClientConfig
(указаны примеры значений или значения по умолчанию):
httpClient {
ok {
followRedirects = true //(1)!
httpVersion = "HTTP_1_1" //(2)!
}
connectTimeout = "5s" //(3)!
readTimeout = "2m" //(4)!
useEnvProxy = false //(5)!
proxy {
host = "localhost" //(6)!
port = 8090 //(7)!
user = "user" //(8)!
password = "password" //(9)!
nonProxyHosts = [ "host1", "host2" ] //(10)!
}
telemetry {
logging {
enabled = false //(11)!
mask = "***" //(12)!
maskQueries = [ ] //(13)!
maskHeaders = [ "authorization" ] //(14)!
pathTemplate = true //(15)!
}
metrics {
enabled = true //(16)!
slo = [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] //(17)!
}
tracing {
enabled = true //(18)!
}
}
}
- Следовать ли по перенаправлениям в HTTP
- Максимальная используемая версия HTTP протокола (доступные значения:
HTTP_1_1
/HTTP_2
/HTTP_3
) - Максимальное время на установление соединения
- Максимальное время на чтение ответа
- Использовать ли переменные окружения для настройки прокси
- Адрес прокси (по умолчанию отсутвует)
- Порт прокси (по умолчанию отсутвует)
- Пользователь для прокси (по умолчанию отсутвует)
- Пароль для прокси (по умолчанию отсутвует)
- Хосты которые следует исключить из проксирования (по умолчанию отсутвует)
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
httpClient:
ok:
followRedirects: true #(1)!
httpVersion: "HTTP_1_1" #(2)!
connectTimeout: "5s" #(3)!
readTimeout: "2m" #(4)!
useEnvProxy: false #(5)!
proxy:
host: "localhost" #(6)!
port: 8090 #(7)!
user: "user" #(8)!
password: "password" #(9)!
nonProxyHosts: [ "host1", "host2" ] #(10)!
telemetry:
logging:
enabled: false #(11)!
mask: "***" #(12)!
maskQueries: [ ] #(13)!
maskHeaders: [ "authorization" ] #(14)!
pathTemplate: true #(15)!
metrics:
enabled: true #(16)!
slo: [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] #(17)!
telemetry:
enabled: true #(18)!
- Следовать ли по перенаправлениям в HTTP
- Максимальная используемая версия HTTP протокола (доступные значения:
HTTP_1_1
/HTTP_2
/HTTP_3
) - Максимальное время на установление соединения
- Максимальное время на чтение ответа
- Использовать ли переменные окружения для настройки прокси
- Адрес прокси (по умолчанию отсутвует)
- Порт прокси (по умолчанию отсутвует)
- Пользователь для прокси (по умолчанию отсутвует)
- Пароль для прокси (по умолчанию отсутвует)
- Хосты которые следует исключить из проксирования (по умолчанию отсутвует)
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
Конфигуратор¶
Пример настройки построителя OkHttp клиента, OkHttpConfigurer
должен быть доступен как компонент:
AsyncHttpClient¶
Реализация HTTP клиента основанная на библиотеке Async HTTP Client. Подходит для Java сервисов, где преобладают асинхронные вызовы.
Подключение¶
Зависимость build.gradle
:
Модуль:
Зависимость build.gradle.kts
:
Модуль:
Конфигурация¶
Пример полной конфигурации, описанной в классе AsyncHttpClientConfig
и HttpClientConfig
(указаны примеры значений или значения по умолчанию):
httpClient {
async {
followRedirects = true //(1)!
}
connectTimeout = "5s" //(2)!
readTimeout = "2m" //(3)!
useEnvProxy = false //(4)!
proxy {
host = "localhost" //(5)!
port = 8090 //(6)!
user = "user" //(7)!
password = "password" //(8)!
nonProxyHosts = [ "host1", "host2" ] //(9)!
}
telemetry {
logging {
enabled = false //(10)!
mask = "***" //(11)!
maskQueries = [ ] //(12)!
maskHeaders = [ "authorization" ] //(13)!
pathTemplate = true //(14)!
}
metrics {
enabled = true //(15)!
slo = [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] //(16)!
}
tracing {
enabled = true //(17)!
}
}
}
- Следовать ли по перенаправлениям в HTTP
- Максимальное время на установление соединения
- Максимальное время на чтение ответа
- Использовать ли переменные окружения для настройки прокси
- Адрес прокси (по умолчанию отсутвует)
- Порт прокси (по умолчанию отсутвует)
- Пользователь для прокси (по умолчанию отсутвует)
- Пароль для прокси (по умолчанию отсутвует)
- Хосты которые следует исключить из проксирования (по умолчанию отсутвует)
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
httpClient:
async:
followRedirects: true #(1)!
connectTimeout: "5s" #(2)!
readTimeout: "2m" #(3)!
useEnvProxy: false #(4)!
proxy:
host: "localhost" #(5)!
port: 8090 #(6)!
user: "user" #(7)!
password: "password" #(8)!
nonProxyHosts: [ "host1", "host2" ] #(9)!
telemetry:
logging:
enabled: false #(10)!
mask: "***" #(11)!
maskQueries: [ ] #(12)!
maskHeaders: [ "authorization" ] #(13)!
pathTemplate: true #(14)!
metrics:
enabled: true #(15)!
slo: [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] #(16)!
telemetry:
enabled: true #(17)!
- Следовать ли по перенаправлениям в HTTP
- Максимальное время на установление соединения
- Максимальное время на чтение ответа
- Использовать ли переменные окружения для настройки прокси
- Адрес прокси (по умолчанию отсутвует)
- Порт прокси (по умолчанию отсутвует)
- Пользователь для прокси (по умолчанию отсутвует)
- Пароль для прокси (по умолчанию отсутвует)
- Хосты которые следует исключить из проксирования (по умолчанию отсутвует)
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
Можно также настроить Netty транспорт.
Java клиент¶
Реализация HTTP клиента на основании встроенного Java клиента поставляемого в JDK. Лучше всего подходит для Java сервисов где не требуется производительность, так как работает прилично медленнее.
Подключение¶
Зависимость build.gradle
:
Модуль:
Зависимость build.gradle.kts
:
Модуль:
Конфигурация¶
Пример полной конфигурации, описанной в классе JdkHttpClientConfig
и HttpClientConfig
(указаны примеры значений или значения по умолчанию):
httpClient {
jdk {
threads = 2 //(1)!
httpVersion = "HTTP_1_1" //(2)!
}
connectTimeout = "5s" //(3)!
useEnvProxy = false //(4)!
proxy {
host = "localhost" //(5)!
port = 8090 //(6)!
user = "user" //(7)!
password = "password" //(8)!
nonProxyHosts = [ "host1", "host2" ] //(9)!
}
telemetry {
logging {
enabled = false //(10)!
mask = "***" //(11)!
maskQueries = [ ] //(12)!
maskHeaders = [ "authorization" ] //(13)!
pathTemplate = true //(14)!
}
metrics {
enabled = true //(15)!
slo = [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] //(16)!
}
tracing {
enabled = true //(17)!
}
}
}
- Количество потоков для HTTP клиента, по умолчанию равен кол-во ядер процессора умноженных на 2
- Какую версию HTTP протокола использовать (доступные значения:
HTTP_1_1
/HTTP_2
) - Максимальное время на установление соединения
- Использовать ли переменные окружения для настройки прокси
- Адрес прокси (по умолчанию отсутвует)
- Порт прокси (по умолчанию отсутвует)
- Пользователь для прокси (по умолчанию отсутвует)
- Пароль для прокси (по умолчанию отсутвует)
- Хосты которые следует исключить из проксирования (по умолчанию отсутвует)
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
httpClient:
jdk:
threads: 2 #(1)!
httpVersion: "HTTP_1_1" #(2)!
connectTimeout: "2s" #(3)!
useEnvProxy: false #(4)!
proxy:
host: "localhost" #(5)!
port: 8090 #(6)!
user: "user" #(7)!
password: "password" #(8)!
nonProxyHosts: [ "host1", "host2" ] #(9)!
telemetry:
logging:
enabled: false #(10)!
mask: "***" #(11)!
maskQueries: [ ] #(12)!
maskHeaders: [ "authorization" ] #(13)!
pathTemplate: true #(14)!
metrics:
enabled: true #(15)!
slo: [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] #(16)!
telemetry:
enabled: true #(17)!
- Количество потоков для HTTP клиента, по умолчанию равен кол-во ядер процессора умноженных на 2
- Какую версию HTTP протокола использовать (доступные значения:
HTTP_1_1
/HTTP_2
) - Максимальное время на установление соединения
- Использовать ли переменные окружения для настройки прокси
- Адрес прокси (по умолчанию отсутвует)
- Порт прокси (по умолчанию отсутвует)
- Пользователь для прокси (по умолчанию отсутвует)
- Пароль для прокси (по умолчанию отсутвует)
- Хосты которые следует исключить из проксирования (по умолчанию отсутвует)
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
Клиент декларативный¶
Предлагается использовать специальные аннотации для создания декларативного клиента:
@HttpClient
— указывает что интерфейс является декларативным HTTP клиентом@HttpRoute
— указывает тип HTTP запроса и путь запроса
Конфигурация клиента¶
Конфигурация конкретной реализации @HttpClient
по умолчанию для поиска конфигурации использует следующий путь httpClient.{имя класса в нижнем регистре}
,
либо указывается в параметре configPath
в аннотации:
Пример конфигурации в случае пути httpClient.someClient
описанной в классе DeclarativeHttpClientConfig
:
httpClient {
someClient {
url = "https://localhost:8090" //(1)!
requestTimeout = "10s" //(2)!
telemetry {
logging {
enabled = false //(3)!
mask = "***" //(4)!
maskQueries = [ ] //(5)!
maskHeaders = [ "authorization" ] //(6)!
pathTemplate = true //(7)!
}
metrics {
enabled = true //(8)!
slo = [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] //(9)!
}
tracing {
enabled = true //(10)!
}
}
}
}
- URL сервиса куда будут отправляться запросы
- Максимальное время запроса
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
httpClient:
someClient:
url: "https://localhost:8090" #(1)!
requestTimeout: "10s" #(2)!
telemetry:
logging:
enabled: false #(3)!
mask: "***" #(4)!
maskQueries: [ ] #(5)!
maskHeaders: [ "authorization" ] #(6)!
pathTemplate: true #(7)!
metrics:
enabled: true #(8)!
slo: [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] #(9)!
telemetry:
enabled: true #(10)!
- URL сервиса куда будут отправляться запросы
- Максимальное время запроса
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
Конфигурация метода¶
На примере выше рассмотренного HTTP клиента, можно настроить отдельно часть параметров для определенного метода, путь к конфигурации
определяется путем к клиенту и именем метода, в примере выше конфигурация httpClient.someClient
и метода hello
финальный путь будет httpClient.someClient.getHello
httpClient {
someClient {
hello {
requestTimeout = "10s" //(1)!
telemetry {
logging {
enabled = false //(2)!
mask = "***" //(3)!
maskQueries = [ ] //(4)!
maskHeaders = [ "authorization" ] //(5)!
pathTemplate = true //(6)!
}
metrics {
enabled = true //(7)!
slo = [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] //(8)!
}
tracing {
enabled = true //(9)!
}
}
}
}
}
- Максимальное время запроса метода
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
httpClient:
someClient:
hello:
requestTimeout: "10s" #(1)!
telemetry:
logging:
enabled: false #(2)!
mask: "***" #(3)!
maskQueries: [ ] #(4)!
maskHeaders: [ "authorization" ] #(5)!
pathTemplate: true #(6)!
metrics:
enabled: true #(7)!
slo: [ 1, 10, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 30000, 60000, 90000 ] #(8)!
telemetry:
enabled: true #(9)!
- Максимальное время запроса метода
- Включает логгирование модуля (по умолчанию
false
) - Маска которая используется для скрытия указанных заголовков и параметров запроса/ответа
- Список параметров запроса которые следует скрывать
- Список заголовков запроса/ответа которые следует скрывать
- Использовать ли всегда шаблон пути запроса при логгировании. По умолчанию используется всегда шаблон пути, за исключением уровня логирования
TRACE
где использует полный путь. - Включает метрики модуля (по умолчанию
true
) - Настройка SLO для DistributionSummary метрики
- Включает трассировку модуля (по умолчанию
true
)
Запрос¶
Секция описывает преобразования HTTP запроса у декларативного HTTP клиента. Предлагается использовать специальные аннотации для указания параметров запроса.
Параметр пути¶
@Path
— обозначает значение части пути запроса, сам параметр указывается в {кавычках}
в пути
и имя параметра указывается в value
либо по умолчанию равно имени аргумента метода.
Параметр запроса¶
@Query
— значение параметра запроса, имя параметра указывается в value
либо по умолчанию равно имени аргумента метода.
Можно отправлять параметры запроса в формате ключ и значение, для этого предполагается использовать тип Map
,
где ключом является имя параметра и обязано иметь тип String
, а значение параметра может быть любым типом и будет обработано через String.valueOf()
:
Заголовок¶
@Header
— значение заголовка запроса, имя параметра указывается в value
либо по умолчанию равно имени аргумента метода.
Можно отправлять параметры запроса в формате ключ и значение, для этого предполагается использовать HttpHeaders
тип либо тип Map
,
где ключом является имя параметра и обязано иметь тип String
, а значение параметра может быть любым типом и будет обработано через String.valueOf()
:
Тело запроса¶
Для указания тела запроса требуется использовать аргумент метода без специальных аннотации,
по умолчанию поддерживаются такие типы как byte[]
, ByteBuffer
или String
.
Json¶
Для указания, что тело является Json и ему требуется автоматически создать такого писателя и внедрить его,
требуется использовать специальную тег аннотацию @Json
:
Требуется подключить модуль Json.
Текстовая форма¶
Можно использовать FormUrlEncoded
как тип аргумента тела форма данных.
Пример вызова метода с такой формой будет выглядеть так:
Бинарная форма¶
Можно использовать FormMultipart
как тип аргумента тела бинарная форма.
Пример вызова метода с такой формой будет выглядеть так:
Самописное¶
Если тело требуется записывать отличным от стандартных механизмов способом,
то можно использовать специальный интерфейс HttpClientRequestMapper
для реализации собственной логики:
@HttpClient
public interface SomeClient {
record UserBody(String id) {}
final class UserRequestMapper implements HttpClientRequestMapper<UserBody> {
@Override
public HttpBodyOutput apply(Context ctx, UserBody value) {
return HttpBody.plaintext(value.id());
}
}
@HttpRoute(method = HttpMethod.POST, path = "/hello/world")
void hello(@Mapping(UserRequestMapper.class) UserBody body);
}
@HttpClient
interface SomeClient {
data class UserBody(val id: String)
class UserRequestMapper : HttpClientRequestMapper<UserBody> {
override fun apply(ctx: Context, value: UserBody): HttpBodyOutput {
return HttpBody.plaintext(value.id)
}
}
@HttpRoute(method = HttpMethod.POST, path = "/hello/world")
fun hello(@Mapping(UserRequestMapper::class) body: UserBody)
}
Куки¶
@Cookie
— значение Cookie, имя параметра указывается в value
либо по умолчанию равно имени аргумента метода.
Обязательные параметры¶
По умолчанию все аргументы объявленные в методе являются обязательными (NotNull).
По умолчанию все аргументы объявленные в методе которые не используют Kotlin Nullability синтаксис считаются обязательными (NotNull).
Необязательные параметры¶
Если аргумент метода является необязательным, то есть может отсутствовать то,
можно использовать аннотацию @Nullable
:
@HttpClient
public interface SomeClient {
@HttpRoute(method = HttpMethod.GET, path = "/hello/world")
void hello(@Nullable @Query("queryValue") String queryValue); //(1)!
}
- Подойдет любая аннотация
@Nullable
, такие какjavax.annotation.Nullable
/jakarta.annotation.Nullable
/org.jetbrains.annotations.Nullable
/ и т.д.
Предполагается использовать Kotlin Nullability синтаксис и помечать такой параметр как Nullable:
Ответ¶
Секция описывает преобразование HTTP ответа от декларативного HTTP клиента.
Тело ответа¶
По умолчанию можно использовать стандартные типы возвращаемых значений тела ответа, такие как void
, byte[]
, ByteBuffer
либо String
.
Json¶
Если предполагается читать тело как Json, то требуется использовать аннотацию @Json
над методом.
Требуется подключить модуль Json.
Сущность ответа¶
Если предполагается читать тело и получить также заголовки и статус код ответа,
то предполагается использовать HttpResponseEntity
, это обертка над телом ответа.
Ниже показан пример аналогичный примеру Json вместе с оберткой HttpResponseEntity
:
Самописное¶
Если требуется чтение ответа отличным способом, то можно использовать специальный интерфейс HttpClientResponseMapper
:
@HttpClient
public interface SomeClient {
record MyResponse(String name) { }
final class ResponseMapper implements HttpClientResponseMapper<MyResponse> {
@Override
public MyResponse apply(HttpClientResponse response) throws IOException, HttpClientDecoderException {
try (var is = response.body().asInputStream()) {
final byte[] bytes = is.readAllBytes();
var body = new String(bytes, StandardCharsets.UTF_8);
return new MyResponse(body);
}
}
}
@Mapping(ResponseMapper.class)
@HttpRoute(method = HttpMethod.GET, path = "/hello/world")
MyResponse hello();
}
@HttpClient
interface SomeClient {
data class MyResponse(val name: String)
class ResponseMapper : HttpClientResponseMapper<MyResponse> {
@Throws(IOException::class, HttpClientDecoderException::class)
override fun apply(response: HttpClientResponse): MyResponse {
response.body().asInputStream().use {
val bytes: ByteArray = it.readAllBytes()
val body = String(bytes, StandardCharsets.UTF_8)
return MyResponse(body)
}
}
}
@Mapping(ResponseMapper::class)
@HttpRoute(method = HttpMethod.GET, path = "/hello/world")
fun hello(): MyResponse
}
Ошибка ответа¶
По умолчанию когда не указан ни какой тег преобразователя ни сам преобразователь, то преобразование будет применяться только для 2хх
HTTP статусов кодов,
для всех остальных будет выбрасываться исключение HttpClientResponseException
, которое содержит HTTP статус код, тело ответа и заголовки ответа.
Преобразование по коду¶
Если требуются специфичные преобразование в зависимости от HTTP статус кода ответа, можно использовать аннотацию @ResponseCodeMapper
для указания
соответствия HTTP статус кода и преобразователя HttpClientResponseMapper
.
Также можно использовать ResponseCodeMapper.DEFAULT
как указание поведения по умолчанию для всех не перечисленных статус кодов.
@HttpClient
public interface SomeClient {
record UserResponse(UserResponse.Payload payload, UserResponse.Error error) {
public record Error(int code, String message) {}
public record Payload(String message) {}
}
@ResponseCodeMapper(code = ResponseCodeMapper.DEFAULT, mapper = ResponseErrorMapper.class)
@ResponseCodeMapper(code = 200, mapper = ResponseSuccessMapper.class)
@HttpRoute(method = HttpMethod.GET, path = "/hello/world")
UserResponse hello();
}
@HttpClient
interface SomeClient {
data class UserResponse(val payload: Payload, val error: Error) {
data class Error(val code: Int, val message: String)
data class Payload(val message: String)
}
@ResponseCodeMapper(code = ResponseCodeMapper.DEFAULT, mapper = ResponseErrorMapper::class)
@ResponseCodeMapper(code = 200, mapper = ResponseSuccessMapper::class)
@HttpRoute(method = HttpMethod.GET, path = "/hello/world")
fun hello(): UserResponse
}
В примере выше для статуса кода 200
будет использовать ResponseSuccessMapper
,
а для всех остальных статус кодов будет использован ResponseErrorMapper
.
Сигнатуры¶
Доступные сигнатуры для методов декларативного HTTP клиента из коробки:
Под T
подразумевается тип возвращаемого значения, либо Void
.
T myMethod()
CompletionStage<T> myMethod()
CompletionStageMono<T> myMethod()
Project Reactor (надо подключить зависимость)
Под T
подразумевается тип возвращаемого значения, либо Unit
.
myMethod(): T
suspend myMethod(): T
Kotlin Coroutine (надо подключить зависимость какimplementation
)
Перехватчики¶
Можно создавать перехватчики для изменения поведения либо создания дополнительного поведения используя класс HttpClientInterceptor
.
Перехватчики можно подключить на определенные методы либо весь @HttpClient
класс целиком:
@HttpClient
public interface SomeClient {
final class MethodInterceptor implements HttpClientInterceptor {
private final Component1 component1;
private MethodInterceptor(Component1 component1) {
this.component1 = component1;
}
@Override
public CompletionStage<HttpClientResponse> processRequest(Context ctx, InterceptChain chain, HttpClientRequest request) throws Exception {
component1.doSomething();
return chain.process(ctx, request);
}
}
@InterceptWith(MethodInterceptor.class)
@HttpRoute(method = HttpMethod.GET, path = "/hello/world")
void hello();
}
@HttpClient
interface SomeClient {
class MethodInterceptor(val component1: Component1) : HttpClientInterceptor {
@Throws(Exception::class)
override fun processRequest(
ctx: Context,
chain: HttpClientInterceptor.InterceptChain,
request: HttpClientRequest
): CompletionStage<HttpClientResponse> {
component1.doSomething()
return chain.process(ctx, request)
}
}
@InterceptWith(MethodInterceptor::class)
@HttpRoute(method = HttpMethod.GET, path = "/hello/world")
fun hello()
}
Авторизация¶
Kora предоставляет готовые перехватчики которые можно использовать для авторизации посредствам Basic/ApiKey/Bearer/OAuth
Basic¶
Требуется сконфигурировать перехватчик и конфигурацию для авторизации Basic:
@Module
public interface BasicAuthModule {
@ConfigSource("openapiAuth.basicAuth")
public interface BasicAuthConfig {
String username();
String password();
}
default BasicAuthHttpClientInterceptor basicAuther(BasicAuthConfig config) {
return new BasicAuthHttpClientInterceptor(config.username(), config.password());
}
}
@Module
interface BasicAuthModule {
@ConfigSource("openapiAuth.basicAuth")
interface BasicAuthConfig {
fun username(): String
fun password(): String
}
fun basicAuther(config: BasicAuthConfig): BasicAuthHttpClientInterceptor {
return BasicAuthHttpClientInterceptor(config.username(), config.password())
}
}
Также в конструктор можно предоставить собственную реализацию HttpClientTokenProvider
если правила получения секретов другие.
Затем подключить перехватчик для всего HTTP клиента либо определенных методов.
ApiKey¶
Требуется сконфигурировать перехватчик и конфигурацию для авторизации ApiKey:
@Module
public interface ApiKeyAuthModule {
@ConfigSource("openapiAuth.apiKeyAuth")
interface ApiKeyAuthConfig {
String apiKey();
}
default ApiKeyHttpClientInterceptor apiKeyAuther(ApiKeyAuthConfig config) {
return new ApiKeyHttpClientInterceptor(ApiKeyLocation.HEADER, "X-API-KEY", config.apiKey());
}
}
Затем подключить перехватчик для всего HTTP клиента либо определенных методов.
Bearer¶
Требуется сконфигурировать перехватчик для авторизации Bearer:
Потребуется самостоятельно реализовать предоставление Bearer
токена с помощью собственной реализации HttpClientTokenProvider
,
либо использовать конструктор который принимает статический Bearer Token
.
public interface HttpClientTokenProvider {
CompletionStage<String> getToken(HttpClientRequest request);
}
Затем подключить перехватчик для всего HTTP клиента либо определенных методов.
OAuth¶
Авторизация посредствам OAuth аналогично Bearer,
требуется самостоятельно реализовать HttpClientTokenProvider
и подложить его в контейнер зависимостей.
Клиент императивный¶
Базовый клиент представляет собой интерфейс HttpClient
и доступен для внедрения:
public interface HttpClient {
CompletionStage<HttpClientResponse> execute(HttpClientRequest request); //(1)!
HttpClient with(HttpClientInterceptor interceptor); //(2)!
}
- Метод исполнения запроса
- Метод позволяющий добавлять различные перехватчики в ручном режиме
Для построения запросов вручную можно использовать HttpClientRequestBuilder
: