在最新版本的 Finch (0.10) 中编译器错误要好一些。如果我们有以下构建配置:
scalaVersion := "2.11.7"
libraryDependencies += "com.github.finagle" %% "finch-core" % "0.10.0"
这个设置:
import com.twitter.finagle.Http
import io.finch._
case class User(id: String, name: String)
def getAllUsers(): List[User] = List(User("111", "Foo McBar"))
val getUsers: Endpoint[List[User]] = get("users") { Ok(getAllUsers()) }
然后当我们尝试使用时toService
,我们得到以下信息:
<console>:18: error: You can only convert a router into a Finagle service if the
result type of the router is one of the following:
* A Response
* A value of a type with an EncodeResponse instance
* A coproduct made up of some combination of the above
List[User] does not satisfy the requirement. You may need to provide an
EncodeResponse instance for List[User] (or for some part of List[User]).
Http.serve(":8080", getUsers.toService)
^
问题是您还没有告诉 Finch 如何将您的User
类型的实例转换为 HTTP 响应。Finch是类型类EncodeResponse
的一个示例,它是一种在 Scala(包括标准库)和许多其他静态类型函数式编程语言中广泛使用的多态性方法。
提供适当EncodeResponse
实例的最简单方法是将 Finch 的Circe兼容性模块添加到您的构建中:
libraryDependencies ++= Seq(
"io.circe" %% "circe-generic" % "0.3.0",
"com.github.finagle" %% "finch-circe" % "0.10.0"
)
然后您只需要以下导入:
import io.finch.circe._, io.circe.generic.auto._
并且toService
可以正常工作:
scala> Http.serve(":8080", getUsers.toService)
Feb 26, 2016 8:32:24 AM com.twitter.finagle.Init$$anonfun$1 apply$mcV$sp
INFO: Finagle version 6.33.0 (rev=21d0ee8b5070b735eda5c84d7aa6fbf1ba7b1635) built at 20160203-202859
res2: com.twitter.finagle.ListeningServer = Group(/0:0:0:0:0:0:0:0:8080)
现在,如果您转到http://localhost:8080/users
,您将看到以下内容:
[{"id":"111","name":"Foo McBar"}]
这看起来很神奇,但发生的事情是相当有原则的。Circe是一个 JSON 库,提供通用编解码器派生,在编译时计算出如何将您的案例类表示为 JSON 值(有关更多上下文,请参阅我的博客文章)。
Finch 食谱是了解更多此类问题的绝佳资源,第一部分详细介绍了提供所需实例EncoderResponse
的其他方法toService
。如果您有任何其他问题或上述任何内容不清楚,请随时在此处或在Gitter上提问。