Finch:方法 'toService' 的参数不足

Finch: not enough arguments for method 'toService'

我使用 Finch 和 Finagle 制作了一个非常简单的休息方法:

val getUsers:Endpoint[List[User]] = get("users") {Ok(getAllUsers())}
Http.serve(":8080", getUsers.toService)

并收到此错误:

Error:(50, 32) not enough arguments for method toService: (implicit ts: io.finch.internal.ToService[List[DAL.Instances.User.User]])com.twitter.finagle.Service[com.twitter.finagle.http.Request,com.twitter.finagle.http.Response].
Unspecified value parameter ts.
  Http.serve(":8080", getUsers.toService)
                               ^

知道如何解决吗?

编译器错误在最新版本的 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 的 EncodeResponsetype class 的一个例子,它是一种在 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 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 值(请参阅我的博客 post 此处了解更多上下文)。

Finch cookbook is a great resource for learning more about questions like this, and the first section goes into detail about other ways to provide the EncoderResponse instances that toService needs. If you have any other questions or if any of the above isn't clear, feel free to ask either here or on Gitter.