HTTP-VERBS-это библиотека Scala, предоставляющая интерфейс для создания асинхронных HTTP-вызовов.
Он инкапсулирует некоторые общие опасения для вызова других услуг HTTP на налоговой платформе HMRC, включая:
См. Чангейлог для изменений и миграций.
В вашей сборке SBT добавить:
resolvers + = MavenRepository ( " HMRC-open-artefacts-maven2 " , " https://open.artefacts.tax.service.gov.uk/maven2 " )
libraryDependencies + = " uk.gov.hmrc " %% " http-verbs-play-xx " % " x.x.x " Где play-xx -ваша версия Play (например, play-30 ).
Доступны два HTTPClicent, но HttpClient и связанный с ними API устарели. Пожалуйста, используйте uk.gov.hmrc.http.client.HttpClientV2 вместо этого.
Этот клиент имеет больше функций, чем оригинальный HttpClient , и его проще в использовании.
Для представления контекста вызывающего абонента требуется HeaderCarrier , а также HttpReads для обработки ответа HTTP.
Это также:
play.api.libs.ws.WSRequest с transform , что облегчает настройку запроса.java.net.URL ; Вы можете использовать предоставленный URL -интерполятор.Примеры можно найти здесь и здесь
Этот клиент устарел. Вы можете мигрировать следующим образом:
httpClient. GET [ ResponseType ](url)становится
httpClientV2.get( url " $url " ).execute[ ResponseType ]и
httpClient. POST [ ResponseType ](url, payload, headers)становится
httpClientV2.post( url " $url " ).withBody( Json .toJson(payload)).setHeader(headers).execute[ ResponseType ]Если вы ранее создавали несколько HTTPClients для настройки прокси или изменения пользовательского агента, это не потребуется, поскольку все это можно контролировать с помощью API HTTPClientV2 за вызов.
HeaderCarrier должен в значительной степени рассматриваться как неизменное представление вызывающего абонента. Если вам нужно манипулировать заголовками, отправляемыми в запросах, вы можете сделать это с помощью API HttpClientV2 .
Например, чтобы переопределить пользовательский агент по умолчанию или заголовок авторизации, определенный в HeaderCarrier, вы можете использовать setHeader , который заменит любые существующие.
httpClientV2.get( url " $url " )
.setHeader( " User-Agent " - > userAgent)
.setHeader( " Authorization " - > authorization)
.execute[ ResponseType ] Если вы хотите добавить к заголовкам по умолчанию, то вы можете получить доступ к addHttpHeaders на базовом WSClient с transform . например
httpClientV2.get( url " $url " )
.transform(_.addHttpHeaders( " User-Agent " - > userAgent))
.execute[ ResponseType ] Имейте в виду, что "Content-Type" не может быть изменен после установки с помощью WSRequest , поэтому, если вы хотите, чтобы другой был определен неявным BodyWriter , вам нужно будет установить его перед предоставлением тела. например
httpClientV2.post( url " $url " )
.setHeader( " Content-Type " - > " application/xml " )
.withBody(< foo >bar</ foo >) С помощью HttpClient для использования прокси, требуемого создания нового экземпляра httpclient для смешивания в WSProxy и настройки. С помощью HttpClientV2 это можно сделать с одним и тем же клиентом, вызовов withProxy за вызов. например
httpClientV2.get( url " $url " ).withProxy.execute[ ResponseType ]WSProxyConfiguration.buildWsProxyServer , который включен с помощью http-verbs.proxy.enabled в конфигурации. Он отключен по умолчанию, что подходит для локальной разработки и тестов, но потребуется включение при развертывании (если еще не включено конфигурацией окружающей среды). Потоковая передача поддерживается HttpClientV2 и будет проверяться так же, как и не потоковые вызовы. Обратите внимание, что полезные нагрузки будут укоренились в журналах аудита, если они превышают поддерживается MAX (как настроено http-verbs.auditing.maxBodyLength ).
Потоковые запросы могут быть просто переданы withBody :
val reqStream : Source [ ByteString , _] = ???
httpClientV2.post( url " $url " ).withBody(reqStream).execute[ ResponseType ] Для потоковых ответов используйте stream , а не execute :
httpClientV2.get( url " $url " ).stream[ Source [ ByteString , _]] Httpclientv2 усекает полезные нагрузки для журналов аудита, если они превышают поддерживается MAX (как настроено http-verbs.auditing.maxBodyLength ).
Это означает, что аудиты, которые были отклонены за то, что они были слишком большими с HTTPClient, вероятно, будут приняты с HTTPClientV2.
Был предоставлен интерполятор URL, чтобы помочь с правильным выбросом запросов и параметров пути.
import uk . gov . hmrc . http . StringContextOps
url " http://localhost:8080/users/ ${user.id} ?email= ${user.email} " HeaderCarrier должен быть создан с помощью HeaderCarrierConverter , когда будет доступен запрос, это гарантирует, что соответствующие заголовки пересылаются на внутренние хосты.
Например, для бэкэндов:
HeaderCarrierConverter .fromRequest(request)и для Frontends:
HeaderCarrierConverter .fromRequestAndSession(request, request.session) Если конечная точка Frontend обслуживает вызов API, он, вероятно, должен использовать fromRequest поскольку fromRequestAndSession будет искать только токен авторизации в сеансе и игнорировать любой, предоставленный в качестве заголовка запроса.
Для асинхронных вызовов, когда запрос не доступен, может быть создан новый HeaderCarrier с параметрами по умолчанию:
HeaderCarrier ()Заголовки пересылаются по -разному в зависимости от того, являются ли они внутренними или внешними . Это различие проводится конфигурацией InternalServiceHostPatterns.
Для внешних хостов отправляется только заголовок пользователя-агента. Любые другие заголовки должны быть явно предоставлены функции глагола ( get , post и т. Д.).
httpClientV2
.get( url " https://externalhost/api " )(hc)
.setHeader( " Authorization " - > " Bearer token " ) // explicit Authorization header for external request В дополнение к пользовательскому агенту, все заголовки, которые явно смоделированы в HeaderCarrier , пересылаются на внутренние хосты. Он также будет пересылать любые другие заголовки в HeaderCarrier , если указано в конфигурации bootstrap.http.headersAllowlist .
Вы можете заменить любой из этих неявно перенаправленных заголовков или добавить любые другие, предоставляя их функции setHeader .
Обратите внимание, что для исходного HttpClient заголовки, предоставленные для функции глагола, отправляются в дополнение к тому, что в HeaderCarrier, поэтому, если вы хотите его заменить, вам придется манипулировать HeaderCarrier например:
client. GET ( " https://internalhost/api " )(hc.copy(authorization = Some ( Authorization ( " Basic 1234 " ))))Ответ дезиализуется примером HTTPreads.
Вы можете либо создать свои собственные экземпляры, либо использовать предоставленные экземпляры с
import uk . gov . hmrc . http . HttpReads . Implicits . _По умолчанию подразумевает (без явного импорта) устарели. Смотрите здесь для более подробной информации.
HttpReads описывает, как преобразовать HttpResponse в вашу модель, используя код состояния и тело ответа.
Предоставленные случаи, внесенные в область при вышеуказанном импорте, позволяют:
client. GET [ HttpResponse ](url) implicit val reads : Reads [ MyModel ] = ???
client.get[ MyModel ](url)UpstreamErrorResponse для не-успешных кодов состояния. Отказы диаграммы JSON также будут возвращены как JsValidationException Эти исключения могут быть восстановлены, если это необходимо.None implict val reads : Reads [ MyModel ] = ???
client.get[ Option [ MyModel ]](url)Either UpstreamErrorResponse implict val reads : Reads [ MyModel ] = ???
client.get[ Either [ UpstreamErrorResponse , MyModel ]](url)В вашей сборке SBT добавьте следующее в ваших тестов -зависимости:
libraryDependencies + = " uk.gov.hmrc " %% " http-verbs-test-play-xx " % " x.x.x " % TestМы рекомендуем, чтобы WiRemock использовался для тестирования кода HTTP-Verbs, с обширными утверждениями по URL, заголовкам и полям тела как для запросов, так и для ответов. Это будет проверять большинство вещей, не включает «издеваться над тем, чего у вас нет», и гарантирует, что изменения в этой библиотеке будут пойманы. То есть, что результат использования этой библиотеки - это то, что было задумано, а не только в том случае, если библиотека была вызвана, как и ожидалось.
Черта WireMockSupport помогает настроить Wiremock для ваших тестов. Он предоставляет wireMockHost , wireMockPort и wireMockUrl , которые можно использовать для надлежащей настройки вашего клиента.
Например, с приложением:
class MyConnectorSpec extends WireMockSupport with GuiceOneAppPerSuite {
override def fakeApplication () : Application =
new GuiceApplicationBuilder ()
.configure(
" connector.host " - > wireMockHost,
" connector.port " - > wireMockPort
).build()
private val connector = app.injector.instanceOf[ MyConnector ]
} Черт HttpClientV2Support может предоставить экземпляр HttpClientV2 в качестве альтернативы инстабилизации приложения:
class MyConnectorSpec extends WireMockSupport with HttpClientV2Support {
private val connector = new MyConnector (
httpClientV2,
Configuration ( " connector.url " - > wireMockUrl)
)
} Черта ExternalWireMockSupport является альтернативой WireMockSupport , которая использует 127.0.0.1 вместо localhost для имени хоста, которое рассматривается как внешний хост для правил передачи заголовка. Это должно использоваться для тестов разъемов, которые вызывают конечные точки, внешние по отношению к платформе. Переменная externalWireMockHost (или externalWireMockUrl ) должна использоваться для обеспечения имени хоста в конфигурации.
Как WireMockSupport , так и ExternalWireMockSupport могут быть использованы вместе для интеграционных тестов, если это необходимо.
Черта ResponseMatchers предоставляет несколько полезных помощников для тестирования ответов.
Этот код является программным обеспечением с открытым исходным кодом, лицензированным по лицензии Apache 2.0.