如何将Akka HTTP(使用自定义指令)迁移到HTTP4S
假设我使用akka http:
- post方法
- 定义此路线,如果
request> request
中有特定的标头
我会删除它,但我会添加一个新的header 具有相同的值(就像我在
request
中更换标题
)一样。我在这里使用自定义指令
。 - 将其提取为
案例类
(YOMEDATA) - 最终在
完成
块中,我有一些代码,它使用request> request
(带有>标题
在步骤2中处理的标题
是这样的:
val someRoute = replaceHeaders {
post {
extractRequest { req =>
entity(as[SomeData]) { someData =>
complete {
// some code here that uses `req` (defined 3 lines above)
}
}
}
}
}
用于替换标题
我可以定义自定义指令
,类似于此:
def replaceHeaders: Directive0 =
mapRequest(req =>
req.headers.find(_.is(headerToReplace)) match {
case Some(header) =>
req
.removeHeader(...)
.addHeader(...(header.value()))
case None => req
}
)
在内部的第一个代码中完整
块我可以访问request
,特别是我可以访问标题
已由replace> replace> replactheaders Directive < /代码>。
如何使用http4s
库进行相同的操作?因为没有像AKKA HTTP
中的自定义指令
。 我知道我可以创建一个函数来执行类似的操作:
def replaceHeaders(request: Request[IO]): Headers = {
val searchHeader = "SomeHeader"
val newHeader = "NewHeader"
request.headers.get(CaseInsensitiveString(searchHeader)) match {
case Some(headerFound) =>
request.headers
.filterNot(_.name == CaseInsensitiveString(searchHeader))
.put(Header(newHeader, headerFound.value))
case None =>
request.headers
}
}
val routes: HttpRoutes[IO] = {
val dsl = Http4sDsl[IO]
import dsl._
HttpRoutes.of[IO] {
case req @ POST -> Root =>
// replace one header for another
val newHeaders = replaceHeaders(req)
IO {
Response[IO](Status.Ok)
.withHeaders(newHeaders)
.withEntity[String]("Process ok.")
}
}
}
但是在这种情况下,我有一个新的标题
的集合:val newheaders = replaceheaders(req)
。 但是akka http
更加灵活,当我更改标题
时,这些都可以作为request> request> except> extractrequest
request> request
的一部分可用。 /代码>。 之后的每个块Extractrequest
访问request> request
时,将具有标题
更新。 但是,在http4s
(至少在我的代码中),我必须明确使用newheaders
才能访问新的headers
。
如何在http4s
中执行相同的操作?
Let's say I define this route using Akka Http:
- POST method
- If there's a specific
header
in therequest
I will remove it but I will add a newheader
with the same value (it is like I'm replacing aheader
in therequest
). I'm using a customdirective
here. - Extract the body as a
case class
(SomeData) - Finally inside the
complete
block I have some code that uses therequest
(with theheaders
processed in step 2)
It would be something like this:
val someRoute = replaceHeaders {
post {
extractRequest { req =>
entity(as[SomeData]) { someData =>
complete {
// some code here that uses `req` (defined 3 lines above)
}
}
}
}
}
For replacing headers
I can define a custom directive
, similar to this:
def replaceHeaders: Directive0 =
mapRequest(req =>
req.headers.find(_.is(headerToReplace)) match {
case Some(header) =>
req
.removeHeader(...)
.addHeader(...(header.value()))
case None => req
}
)
In the first code inside the complete
block I have access to the request
, in particular I have access to the headers
that has been processed by replaceHeaders directive
.
How can I do the same using http4s
library? Because there are no customized directive
as in Akka Http
.
I know I can create a function to do something similar:
def replaceHeaders(request: Request[IO]): Headers = {
val searchHeader = "SomeHeader"
val newHeader = "NewHeader"
request.headers.get(CaseInsensitiveString(searchHeader)) match {
case Some(headerFound) =>
request.headers
.filterNot(_.name == CaseInsensitiveString(searchHeader))
.put(Header(newHeader, headerFound.value))
case None =>
request.headers
}
}
val routes: HttpRoutes[IO] = {
val dsl = Http4sDsl[IO]
import dsl._
HttpRoutes.of[IO] {
case req @ POST -> Root =>
// replace one header for another
val newHeaders = replaceHeaders(req)
IO {
Response[IO](Status.Ok)
.withHeaders(newHeaders)
.withEntity[String]("Process ok.")
}
}
}
But in this case I have a new collection of headers
: val newHeaders = replaceHeaders(req)
.
But Akka Http
is more flexible, when I make changes to the headers
these are immediately available as part of the request
after extractRequest
. Every block after extractRequest
when accessing the request
will have the headers
updated.
But in the case of http4s
(at least in my code) I have to explicitly use newHeaders
to access the new headers
.
How can I do the same in http4s
?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论