HTTP-verbs是一個Scala庫,提供了一個接口來進行異步HTTP調用。
它封裝了在HMRC稅收平台上調用其他HTTP服務的一些常見問題,包括:
有關更改和遷移,請參見Changelog。
在您的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-30 )。
有兩種可用的HTTPCLIENT,但是HttpClient和相關的API已被棄用。請改用uk.gov.hmrc.http.client.HttpClientV2 。
該客戶端的功能比原始的HttpClient具有更多的功能,並且更易於使用。
它需要一個HeaderCarrier來表示呼叫者的上下文,並且HttpReads來處理HTTP響應。
它也是:
transform揭示基礎play.api.libs.ws.WSRequest ,使自定義請求更加容易。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 ]如果您以前創建了多個HTTPCLIENT來配置代理或更改用戶代理,則無需更長時間,因為這些都可以通過每個呼叫的HTTPCLIENTV2 API來控制。
HeaderCarrier應在很大程度上被視為呼叫者的不變代表。如果您需要操縱在請求中發送的標題,則可以使用HttpClientV2 API執行此操作。
例如,要覆蓋頭架上定義的默認用戶代理或授權標頭,您可以使用將替換任何現有的setHeader 。
httpClientV2.get( url " $url " )
.setHeader( " User-Agent " - > userAgent)
.setHeader( " Authorization " - > authorization)
.execute[ ResponseType ]如果您想附加到默認標頭,則可以通過transform訪問基礎WSClient上的addHttpHeaders 。例如
httpClientV2.get( url " $url " )
.transform(_.addHttpHeaders( " User-Agent " - > userAgent))
.execute[ ResponseType ]請注意,一旦使用WSRequest設置"Content-Type"因此,如果您希望與隱式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支持,並將以與非流式調用相同的方式進行審核。請注意,如果有效載荷超過了支持的最大值(如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如果超過支持的最大值(如http-verbs.auditing.maxBodyLength配置),則審核日誌的有效載荷截斷了。
這意味著因HTTPCLIENT太大而被拒絕的審核可能會被HTTPCLIENTV2接受。
已經提供了URL插值器,以幫助正確逃脫查詢和路徑參數。
import uk . gov . hmrc . http . StringContextOps
url " http://localhost:8080/users/ ${user.id} ?email= ${user.email} "在可用請求時,應使用HeaderCarrierConverter創建HeaderCarrier ,這將確保將適當的標頭轉發給內部主機。
例如,用於後端:
HeaderCarrierConverter .fromRequest(request)對於前端:
HeaderCarrierConverter .fromRequestAndSession(request, request.session)如果前端端點正在為API調用提供服務,則可能會使用fromRequest ,因為fromRequestAndSession只會在會話中尋找授權令牌,而忽略提供的任何作為請求標題的授權令牌。
對於異步調用,如果沒有可用的請求,則可以使用默認參數創建新的頭架:
HeaderCarrier ()根據內部還是外部的不同,將標題轉發給宿主。這種區別是由InternalServiceHostPatterns配置進行的。
對於外部主機,僅發送用戶代理標頭。任何其他標題都應明確提供到動詞功能( get , post等)。
httpClientV2
.get( url " https://externalhost/api " )(hc)
.setHeader( " Authorization " - > " Bearer token " ) // explicit Authorization header for external request 除了用戶代理外,所有在HeaderCarrier中明確建模的標頭都將轉發給內部主機。如果在bootstrap.http.headersAllowlist配置中列出,則還將轉發HeaderCarrier的任何其他標頭。
您可以替換這些隱式轉發的標題中的任何一個,也可以通過將其提供給setHeader功能來添加任何其他標題。
請注意,對於原始的HttpClient ,提供給動詞功能的標頭除了輔助手機中的那些外,還將發送,因此,如果您想替換一個,則必須操縱HeaderCarrier EG:
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的hostName的WireMockSupport的替代方案,該主機被視為標題轉發規則的外部主機。這應用於調用平台外部端點的連接器的測試。應使用可變的externalWireMockHost (或externalWireMockUrl )在配置中提供主機名。
如果需要,可以將WireMockSupport和ExternalWireMockSupport一起用於集成測試。
ResponseMatchers特徵為測試響應提供了一些有用的幫助者。
此代碼是根據Apache 2.0許可證許可的開源軟件。