Scala 处理在Spray中返回Try值的服务

Scala 处理在Spray中返回Try值的服务,scala,try-catch,spray,spray-dsl,Scala,Try Catch,Spray,Spray Dsl,我正在开发一个代码库,在这个代码库中,调用Spray API需要同步调用一个服务,该服务返回Spray需要格式化并通过HTTP返回的Try 我最初的尝试是这样的: // Assume myService has a run method that returns a Try[Unit] lazy val myService = new Service() val routes = path("api") { get { tryToComplete {

我正在开发一个代码库,在这个代码库中,调用Spray API需要同步调用一个服务,该服务返回Spray需要格式化并通过HTTP返回的Try

我最初的尝试是这样的:

// Assume myService has a run method that returns a Try[Unit]
lazy val myService = new Service() 

val routes = 
  path("api") {
    get {
      tryToComplete {
        myService.run()
      } 
    }
  } ~ 
  path("api" / LongNumber) { (num: Long) =>
    get {
      tryToComplete {
        myService.run(num)
      } 
    }
  }

def tryToComplete(result: => Try[Unit]): routing.Route = result match {
  case Failure(t) => complete(StatusCodes.BadRequest, t.getMessage)
  case Success(_) => complete("success")
}
但是,这导致在应用程序启动时调用
myService.run()
。我不知道为什么调用这个方法,因为没有进行HTTP调用

所以我有两个问题:

  • 为什么我的服务作为初始化路线的一部分被调用
  • 处理这个案子最干净的方法是什么?假设有几个其他端点遵循类似的模式。所以我需要能够始终如一地处理这个问题

  • 即使您将结果参数命名为callby name,它也会在执行时立即得到评估

    result match {
    
    要使其不被评估,它必须在完整的范围内,即您的代码应该类似(尚未尝试编译此代码):


    我解决这个问题的方法是执行以下操作:

    lazy val myService = new Service() 
    
    val routes = 
      path("api") {
        get {
          complete {
            handleTry {
              myService.run()
            }
          } 
        }
      } ~ 
      path("api" / LongNumber) { (num: Long) =>
        get {
          complete {
             handleTry {
              myService.run(num)
            } 
          }
        }
      }
    
    private def handleTry(operation: Try[_]):HttpResponse = operation match {
      case Failure(t) => 
        HttpResponse(status = StatusCodes.BadRequest, entity = t.getMessage)
      case Success(_) => 
        HttpResponse(status = StatusCodes.OK, entity = successMessage)
    }
    
    lazy val myService = new Service() 
    
    val routes = 
      path("api") {
        get {
          complete {
            handleTry {
              myService.run()
            }
          } 
        }
      } ~ 
      path("api" / LongNumber) { (num: Long) =>
        get {
          complete {
             handleTry {
              myService.run(num)
            } 
          }
        }
      }
    
    private def handleTry(operation: Try[_]):HttpResponse = operation match {
      case Failure(t) => 
        HttpResponse(status = StatusCodes.BadRequest, entity = t.getMessage)
      case Success(_) => 
        HttpResponse(status = StatusCodes.OK, entity = successMessage)
    }