在使用Scala、akka http、Json4s的微服务中,在哪里定义隐式val格式?

在使用Scala、akka http、Json4s的微服务中,在哪里定义隐式val格式?,scala,json4s,akka-http,Scala,Json4s,Akka Http,我正在使用Scala、akka http、json4s构建一个微服务。还为我的业务bean类使用case类。我的案例类有scala枚举(我研究了scala枚举并意识到其局限性,但这非常适合我当前的用例) 在这种背景下,当我尝试创建服务时,我无法理解在哪里定义服务 implicit val formats=DefaultFormats+新的枚举器(_ProfessionClaType)+新的枚举器(_LinkRelType) 下面是我粗略的scala类结构: import akka.actor.A

我正在使用Scala、akka http、json4s构建一个微服务。还为我的业务bean类使用case类。我的案例类有scala枚举(我研究了scala枚举并意识到其局限性,但这非常适合我当前的用例)

在这种背景下,当我尝试创建服务时,我无法理解在哪里定义服务

implicit val formats=DefaultFormats+新的枚举器(_ProfessionClaType)+新的枚举器(_LinkRelType)

下面是我粗略的scala类结构:

import akka.actor.ActorSystem
import akka.event.{Logging, LoggingAdapter}
import akka.http.scaladsl.Http
import akka.http.scaladsl.marshalling.ToResponseMarshallable
import akka.http.scaladsl.model.StatusCodes._
import akka.http.scaladsl.server.Directives
import akka.stream.ActorMaterializer
import com.typesafe.config.{Config, ConfigFactory}
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import gremlin.scala.ScalaVertex
import org.apache.tinkerpop.gremlin.structure.util.detached.DetachedVertex
import org.json4s.ext.EnumNameSerializer
import org.json4s.{DefaultFormats, jackson}
import scala.concurrent.{ExecutionContext, ExecutionContextExecutor, Future}

trait Service {
  implicit val system: ActorSystem
  implicit def executor: ExecutionContextExecutor
  implicit val materializer: ActorMaterializer
 // ?? implicit val formats = DefaultFormats + new EnumNameSerializer(_ProfessionClaType) + new EnumNameSerializer(_LinkRelType)
 lazy val client = TitanConnection.cluster.connect();

  def config: Config
  val logger: LoggingAdapter

  def addPerson(p: Person): Future[Either[String, Person]] = {
    try {
      //Code to add person to database
      val resultPerson = Person(propertyMap)
      Future.successful(Right(resultPerson))
    } catch {
      case e :Exception => e.printStackTrace
        Future.failed(new Exception("Person can't be created"))
    }
  }

  def fetchPerson(pId: String): Future[Either[Error, Person]] = {
    try {
      //Code to fetch person object from database
      result = results.one() //fetches the first record from results, if it exists
      //Following is code for validation of the data
      if(result.isNull)
        Future.successful(Left(new Error("FAILED","","",s"""There is no person with requested personID:$pId""")))
      else {
        //Code to retrieve person and return the same as object
        Future.successful(Right(resultPerson))
      }
    } catch {
      case e :Exception => e.printStackTrace
        Future.successful(Left(new Error("FATAL","","",s"""There is some exception while retrieving person with requested personID:$pId""")))
    }
  }

  /** This is the list of operations possible on the person business entity.
   *
   * @param ec
   * @return
   */
  def routes(implicit ec: ExecutionContext) = {
    import Directives._
    import Json4sSupport._
    implicit val serialization = jackson.Serialization // or native.Serialization
    implicit val system = ActorSystem()
    implicit val materializer = ActorMaterializer()
    implicit val formats = DefaultFormats + new EnumNameSerializer(_ProfessionClaType) + new EnumNameSerializer(_LinkRelType)

    logRequestResult("PersonMicroservice") {
      pathPrefix("person") {

        (get & path(Segment)) { personId =>
          implicit val formats = DefaultFormats + new EnumNameSerializer(_ProfessionClaType) + new EnumNameSerializer(_LinkRelType)
          complete {
            fetchPerson(personId).map[ToResponseMarshallable] {
              case Right(personFormat) => personFormat
              case Left(errorMessage) => BadRequest -> errorMessage
            }
          }
        }~
        post { entity(as[Person]) { entity =>
           implicit val formats = DefaultFormats + new EnumNameSerializer(_ProfessionClaType) + new EnumNameSerializer(_LinkRelType)
           complete {
              addPerson(entity).map[ToResponseMarshallable] {
                  case Right(personFormat) => personFormat
                  case Left(error) => BadRequest -> error
                }
            }
          }
        }
      }
    }
  }
}

/** Microservice for "Person" business entity. This microservice shall handle the basic CRUD related operations
 * of Person business entity.
 */
object PersonMicroService extends App with Service {
  override implicit val system = ActorSystem()
  override implicit val executor = system.dispatcher
  override implicit val materializer = ActorMaterializer()
  override val config = ConfigFactory.load()
  override val logger = Logging(system, getClass)
  Http().bindAndHandle(routes , config.getString("http.interface"), config.getInt("http.port"))
}
我还有一个ScalaTest规范用于对服务进行单元测试,我还被迫在每个测试用例中定义
格式。不确定我是否做对了。因此寻求专家建议

以下是我的测试规范:

包装在.niftyride.unit中

import akka.event.{Logging, LoggingAdapter}
import akka.http.scaladsl.server.Directives
import de.heikoseeberger.akkahttpjson4s.Json4sSupport
import org.json4s.{jackson, DefaultFormats}
import org.json4s.ext.EnumNameSerializer
import akka.http.scaladsl.model.ContentTypes._
import akka.http.scaladsl.model.StatusCodes._
import Json4sSupport._

class PersonEndpointSpec extends UnitServiceSpec{
  override def testConfigSource = "akka.loglevel = WARNING"
  override def config = testConfig
  override lazy val client = TestDatabaseProvider.cluster.connect;
  val logger: LoggingAdapter = Logging(system, this.getClass)
  System.setProperty(DatabaseUtils.SERVER_HASH_TEXT, DatabaseUtils.RANDOM_HASH)

  "Service" should "respond to single id query" in {
    implicit val serialization = jackson.Serialization // or native.Serialization
    implicit val formats = DefaultFormats + new EnumNameSerializer(_ProfessionClaType) + new EnumNameSerializer(_LinkRelType)
    Get(s"/person/${PersonTestData.personId1}") ~> routes ~> check {
      status shouldBe OK
      contentType shouldBe `application/json`
      responseAs[Person] shouldBe PersonTestData.minData1
    }
  }
  it should "be possible to create a person with valid data through POST" in {
    implicit val serialization = jackson.Serialization // or native.Serialization
    implicit val formats = DefaultFormats + new EnumNameSerializer(_ProfessionClaType) + new EnumNameSerializer(_LinkRelType)
    Post(s"/person", PersonTestData.minDataEmptyPersonId1) ~> routes ~> check {
      status shouldBe OK
      contentType shouldBe `application/json`
      responseAs[Person] shouldBe PersonTestData.minData1
    }
  }
}

更令人困惑的是,隐式值是在随后的重新启动中拾取而不是拾取的(没有代码更改)将
implicit val serialization=jakson.serialization
更改为
implicit val serialization=native.serialization
后,IntelliJA中的微服务的序列化和反序列化工作且至少不间断(在多次重新启动期间工作)。