2016-02-26 7 views
5

ich eine ziemlich einfache Rest-Methode gemacht haben mit Fink und Finagle:Finch: nicht genügend Argumente für die Methode 'toService'

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

und bekam diesen Fehler:

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) 
          ^

Jede Idee, wie man es repariert?

Antwort

10

Der Compiler-Fehler ist ein wenig besser in der neuesten Version von Finch (0,10).

scalaVersion := "2.11.7" 

libraryDependencies += "com.github.finagle" %% "finch-core" % "0.10.0" 

Und diese Einstellung: Wenn wir die folgende Build-Konfiguration haben

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()) } 

Dann, wenn wir versuchen, toService zu verwenden, erhalten wir folgendes:

<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) 
            ^

Das Problem ist, dass Sie haben Finch nicht gesagt, wie Sie Instanzen Ihres User Typs in HTTP-Antworten übersetzen. Finchs EncodeResponse ist ein Beispiel für eine type class, die ein Ansatz für Polymorphie ist, die in Scala (einschließlich der Standardbibliothek) und vielen anderen statisch typisierten funktionalen Programmiersprachen weit verbreitet ist.

Der einfachste Weg, die entsprechenden EncodeResponse Instanzen zu schaffen, ist Finch Circe Kompatibilitätsmodul zu Ihrer Build hinzuzufügen:

libraryDependencies ++= Seq(
    "io.circe" %% "circe-generic" % "0.3.0", 
    "com.github.finagle" %% "finch-circe" % "0.10.0" 
) 

Und dann alles, was Sie brauchen, ist die folgenden Importe:

import io.finch.circe._, io.circe.generic.auto._ 

Und toService wird gut funktionieren:

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) 
Jetzt

wenn Sie http://localhost:8080/users gehen, sehen Sie folgendes:

[{"id":"111","name":"Foo McBar"}] 

Das sieht aus wie Magie, aber was passiert, ist ziemlich prinzipien. Circe ist eine JSON-Bibliothek, die generische Codec-Ableitung bereitstellt, die zur Kompilierungszeit herausstellt, wie Sie Ihre Fallklassen als JSON-Werte darstellen (siehe meinen Blogbeitrag here für mehr Kontext).

Die Finch cookbook ist eine großartige Ressource für mehr über Fragen wie diese zu lernen, und der erste Abschnitt geht ins Detail über andere Möglichkeiten, um die EncoderResponse Instanzen dass toService Bedürfnisse zu sorgen. Wenn Sie noch weitere Fragen haben oder eine der oben genannten Fragen nicht klar ist, wenden Sie sich bitte an uns oder unter Gitter.

+0

Danke, Travis! –

+0

Vielen Dank! – NikitaAbrosimov

+0

selbst nach dem Importieren von io.finch.circe._, io.circe.generic.auto._, klagt scala ide über _not genug Argumente für die Methode toService: _. Irgendwelche anderen Vorschläge? – Rjk

Verwandte Themen