Finch: not enough arguments for 'toService' method

I made a fairly simple rest method using Finch and Finagle:

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

and got this error:

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

Any idea on how to fix it?

+5
source share
1 answer

The compiler error is slightly better in the latest version of Finch (0.10). If we have the following build configuration:

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

And this setting:

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

Then, when we try to use toService , we get the following:

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

The problem is that you did not tell Finch how to translate instances of your User type into HTTP responses. Finch EncodeResponse is an example of a type class that represents a polymorphism approach that is widely used in Scala (including the standard library) and many other statically typed functional programming languages.

The easiest way to provide the appropriate EncodeResponse instances is to add the Finch Circe compatibility module to your assembly:

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

And then you only need to import:

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

And toService will work fine:

 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) 

Now, if you go to http://localhost:8080/users , you will see the following:

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

It looks like magic, but what happens is pretty basic. Circe is a JSON library that provides general codec output that compiles at compile time how to present your case classes as JSON values ​​(see my blog post here for more context).

The Finch cookbook is an excellent resource for more detailed study of such issues, and the first section details other ways to provide EncoderResponse instances that are toService . If you have other questions or if any of the above questions is not clear, feel free to ask here or on Gitter .

+10
source

Source: https://habr.com/ru/post/1243918/


All Articles