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许可证许可的开源软件。