2016-02-26 7 views
5

ho fatto un riposo metodo piuttosto semplice utilizzando Finch e Finagle:Finch: non abbastanza argomenti per il metodo 'toService'

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

e ottenuto questo errore:

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

Qualche idea su come sistemarlo?

risposta

10

L'errore del compilatore è leggermente migliore nella versione più recente di Finch (0.10). Se abbiamo la seguente configurazione di generazione:

scalaVersion := "2.11.7" 

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

E questa configurazione:

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

Poi, quando si tenta di utilizzare toService, otteniamo la seguente:

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

Il problema è che non hai detto a Finch come tradurre istanze del tuo tipo User in risposte HTTP. Finch's EncodeResponse è un esempio di type class, che è un approccio al polimorfismo ampiamente utilizzato in Scala (inclusa la libreria standard) e molti altri linguaggi di programmazione funzionale tipizzati staticamente.

Il modo più semplice per fornire le appropriate EncodeResponse casi è quello di aggiungere il modulo Circe compatibilità di Finch alla costruzione:

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

E poi tutto ciò che serve è la seguente importazioni:

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

E toService funzionerà bene:

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) 

Ora, se si va a http://localhost:8080/users, vedrete il seguente:

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

Questo appare come per magia, ma ciò che sta accadendo è abbastanza di principio. Circe è una libreria JSON che fornisce una derivazione generica di codec che calcola in fase di compilazione come rappresentare le classi case come valori JSON (vedere il mio post del blog here per ulteriori informazioni).

Finch cookbook è una grande risorsa per ulteriori informazioni su domande come questa e la prima sezione descrive in dettaglio altri modi per fornire le istanze EncoderResponse richieste da toService. Se hai altre domande o se uno dei precedenti non è chiaro, non esitare a chiedere qui o allo Gitter.

+0

Grazie, Travis! –

+0

Grazie mille! – NikitaAbrosimov

+0

anche dopo aver importato io.finch.circe._, io.circe.generic.auto._, scala ide si lamenta di _non sufficienti argomenti per il metodo toService: _. qualche altro suggerimento? – Rjk

Problemi correlati