为了提供一个完整的工作示例,我会假设有一个类似于这样的case class:
```scala
case class Person(name: String, age: Int)
```
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的通用派生(generic derivation)来自动将“created”Test
编码为JSON格式并作为响应返回。
您还可以使用Circe来派生请求体的读取器:
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
之一(请参考文档获取更完整的列表),然后在Endpoint
上使用as
、map
等方法,将其转换成所需的形状。
Test
具有类型为scalaz.Maybe
的字段。将其作为Option
可以工作,但是如何使其与Maybe
一起工作(出于几个原因,我更喜欢Maybe
而不是Option
)?我一直收到“尝试在失败的光标上解码值”的错误信息。 - sloucscalaz.Maybe[A: Decoder]
定义一个单独的通用实例,但需要更多细节。 - Travis Brown