1

在 finch 中,我们可以像这样定义路由器、请求参数、请求体。

  case class Test(name: String, age: Int)

  val router: Endpoint[Test] = post("hello") { Ok(Test("name", 30)) }
  val requestBody: Endpoint[Test] = body.as[Test]
  val requestParameters: Endpoint[Test] = Endpoint.derive[Test].fromParams

好处是我们可以将 EndPoint 组合在一起。例如,我可以定义:

请求路径是hello并且Parameter应该有nameage。( router :: requestParameters)

但是,我仍然可以成功运行不包含任何请求路径的无效端点(实际上没有编译错误)

Await.ready(Http.serve(":3000", requestParameters.toService)) 

结果返回 404 not found 页面。即使我希望错误应该像编译错误一样早点报告。我想知道这是设计缺陷还是实际上是雀试图修复的?

提前谢谢了

4

1 回答 1

2

首先,非常感谢您提出这个问题!

让我给你一些关于 Finch 端点如何工作的见解。如果你说范畴论,anEndpoint是一个Applicative嵌入,StateT表示为接近Input => Option[(Input, A)].

简单来说,端点接受一个Input包装 HTTP 请求并捕获当前路径(例如:)的端点/foo/bar/baz。当端点应用于给定请求并匹配它(返回Some)或失败(返回None)。匹配时,它会更改 的状态Input,通常从中删除第一个路径段(例如:从 删除foo/foo/bar/baz,因此下一个端点是链可以使用新的Input(和新的路径)。

一旦端点匹配,Finch 会检查是否还有其他Input不匹配的内容。如果有剩余,则认为匹配不成功,您的服务返回 404。

scala> val e = "foo" :: "bar"
e: io.finch.Endpoint[shapeless.HNil] = foo/bar

scala> e(Input(Request("/foo/bar/baz"))).get._1.path
res1: Seq[String] = List(baz)

当涉及到端点匹配/提取查询字符串参数时,那里没有路径段被触及,状态被传递到下一个端点不变。因此,当应用端点param("foo")时,路径不会受到影响。这只是意味着,提供查询字符串端点(注意:仅提取查询字符串参数的端点)的唯一方法是向它发送一个带有空路径的请求/

scala> val s = param("foo").toService
s: com.twitter.finagle.Service[com.twitter.finagle.http.Request,com.twitter.finagle.http.Response] = <function1>

scala> s(Request("/", "foo" -> "bar")).get
res4: com.twitter.finagle.http.Response = Response("HTTP/1.1 Status(200)")

scala> s(Request("/bar", "foo" -> "bar")).get
res5: com.twitter.finagle.http.Response = Response("HTTP/1.1 Status(404)")
于 2016-05-02T17:55:29.740 回答