2016-02-26 14 views
5

Tôi đã thực hiện một phần còn lại-phương pháp khá đơn giản sử dụng Finch và Finagle:Finch: không đủ lập luận cho phương pháp 'toService'

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

và đã nhận lỗi này:

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

Bất kỳ ý tưởng về làm thế nào để sửa chữa nó?

Trả lời

10

Lỗi trình biên dịch tốt hơn một chút trong phiên bản mới nhất của Finch (0.10). Nếu chúng ta có xây dựng cấu hình sau:

scalaVersion := "2.11.7" 

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

Và thiết lập này:

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

Sau đó, khi chúng tôi cố gắng sử dụng toService, chúng tôi nhận được những điều sau đây:

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

Vấn đề là bạn chưa nói với Finch cách dịch các phiên bản loại User của bạn thành các phản hồi HTTP. Finch's EncodeResponse là một ví dụ về type class, là một cách tiếp cận đa hình được sử dụng rộng rãi trong Scala (bao gồm thư viện chuẩn) và nhiều ngôn ngữ lập trình hàm tĩnh khác.

Cách đơn giản nhất để cung cấp các EncodeResponse trường hợp thích hợp là thêm mô-đun Circe tương thích Finch để xây dựng của bạn:

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

Và sau đó tất cả các bạn cần là hàng nhập khẩu như sau:

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

toService sẽ hoạt động tốt:

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) 

Bây giờ nếu bạn đi đến http://localhost:8080/users, bạn sẽ thấy như sau:

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

này trông giống như ma thuật, nhưng những gì đang xảy ra là khá nguyên tắc. Circe là thư viện JSON cung cấp dẫn xuất codec chung để tính toán thời gian biên dịch cách thể hiện các lớp chữ hoa của bạn dưới dạng giá trị JSON (xem bài đăng blog của tôi here để biết thêm ngữ cảnh).

Finch cookbook là tài nguyên tuyệt vời để tìm hiểu thêm về các câu hỏi như thế này và phần đầu tiên đi vào chi tiết về các cách khác để cung cấp các yêu cầu EncoderResponse nhu cầu toService. Nếu bạn có bất kỳ câu hỏi nào khác hoặc nếu bất kỳ câu hỏi nào ở trên không rõ ràng, vui lòng hỏi tại đây hoặc theo số Gitter.

+0

Cảm ơn bạn, Travis! –

+0

Cảm ơn bạn rất nhiều! – NikitaAbrosimov

+0

ngay cả sau khi nhập io.finch.circe._, io.circe.generic.auto._, scala ide đang phàn nàn về _không đủ đối số cho phương thức toService: _. bất cứ một đề nghị nào khác? – Rjk

Các vấn đề liên quan