如何在 Finch 中绑定请求体
how to bind request body in Finch
这是将请求参数绑定到路由器的代码。
val testReader: Endpoint[Test] = Endpoint.derive[Test].fromParams
val test: Endpoint[String] = post("test" ? testReader) { t : Test => {
Created("OK")
}}
我正在使用方法fromParams
。这个方法可以很酷的绑定请求参数。但是,我不知道我可以用哪种类似的方式在 finch
中绑定 request body
非常感谢
为了提供一个完整的工作示例,我将假设这样一个案例 class:
case class Test(foo: Int, bar: String)
还有一些这样的请求:
import com.twitter.finagle.http.{ Method, Request, RequestBuilder }
import com.twitter.io.{ Buf, Reader }
val queryParamPost = Request(Method.Post, "/test?foo=1&bar=whatever")
val testJsonBuf = Buf.Utf8("""{ "foo": 1, "bar": "whatever" }""")
val bodyPost = RequestBuilder().url("http://localhost:8080/test").buildPost(testJsonBuf)
现在当你写下以下内容时……
import io.finch._
val testParams: Endpoint[Test] = Endpoint.derive[Test].fromParams
val test: Endpoint[Test] = post("test" ? testParams) { test: Test =>
Created(test)
}
发生的事情是 Finch 使用泛型推导(由 Shapeless 提供支持)来确定(在编译时)如何将查询参数解析为 Test
。然后您可以像这样测试端点:
import io.finch.circe._
import io.circe.generic.auto._
test.toService.apply(queryParamPost).onSuccess { response =>
println(s"$response: ${ response.contentString }")
}
将打印:
Response("HTTP/1.1 Status(201)"): {"foo":1,"bar":"whatever"}
在这里,我使用 Circe 的泛型推导自动将 "created" Test
编码为 JSON 作为响应。
您还可以使用 Circe 为请求主体派生一个 reader:
val testBody: Endpoint[Test] = body.as[Test]
val test2: Endpoint[Test] = post("test" :: testBody) { test: Test =>
Created(test)
}
这与上面的 test
几乎完全相同,但是我们使用 body
来获取一个 Endpoint[String]
来读取请求正文,然后 as
指定我们希望将内容解析为 JSON 并解码为 Test
值。我们可以像这样测试这个新版本:
test2.toService.apply(bodyPost).onSuccess { response =>
println(s"$response: ${ response.contentString }")
}
我们会再次得到我们期待的答案。
一般来说,当您想读取传入请求的某种信息时,您将使用 Finch 提供的基本 Endpoint
之一(更完整的信息请参阅 the docs列表),然后在Endpoint
上使用as
、map
等方法将其变成你需要的形状。
这是将请求参数绑定到路由器的代码。
val testReader: Endpoint[Test] = Endpoint.derive[Test].fromParams
val test: Endpoint[String] = post("test" ? testReader) { t : Test => {
Created("OK")
}}
我正在使用方法fromParams
。这个方法可以很酷的绑定请求参数。但是,我不知道我可以用哪种类似的方式在 finch
非常感谢
为了提供一个完整的工作示例,我将假设这样一个案例 class:
case class Test(foo: Int, bar: String)
还有一些这样的请求:
import com.twitter.finagle.http.{ Method, Request, RequestBuilder }
import com.twitter.io.{ Buf, Reader }
val queryParamPost = Request(Method.Post, "/test?foo=1&bar=whatever")
val testJsonBuf = Buf.Utf8("""{ "foo": 1, "bar": "whatever" }""")
val bodyPost = RequestBuilder().url("http://localhost:8080/test").buildPost(testJsonBuf)
现在当你写下以下内容时……
import io.finch._
val testParams: Endpoint[Test] = Endpoint.derive[Test].fromParams
val test: Endpoint[Test] = post("test" ? testParams) { test: Test =>
Created(test)
}
发生的事情是 Finch 使用泛型推导(由 Shapeless 提供支持)来确定(在编译时)如何将查询参数解析为 Test
。然后您可以像这样测试端点:
import io.finch.circe._
import io.circe.generic.auto._
test.toService.apply(queryParamPost).onSuccess { response =>
println(s"$response: ${ response.contentString }")
}
将打印:
Response("HTTP/1.1 Status(201)"): {"foo":1,"bar":"whatever"}
在这里,我使用 Circe 的泛型推导自动将 "created" Test
编码为 JSON 作为响应。
您还可以使用 Circe 为请求主体派生一个 reader:
val testBody: Endpoint[Test] = body.as[Test]
val test2: Endpoint[Test] = post("test" :: testBody) { test: Test =>
Created(test)
}
这与上面的 test
几乎完全相同,但是我们使用 body
来获取一个 Endpoint[String]
来读取请求正文,然后 as
指定我们希望将内容解析为 JSON 并解码为 Test
值。我们可以像这样测试这个新版本:
test2.toService.apply(bodyPost).onSuccess { response =>
println(s"$response: ${ response.contentString }")
}
我们会再次得到我们期待的答案。
一般来说,当您想读取传入请求的某种信息时,您将使用 Finch 提供的基本 Endpoint
之一(更完整的信息请参阅 the docs列表),然后在Endpoint
上使用as
、map
等方法将其变成你需要的形状。