0
votes

I am new in Scala Akka httpd and I am trying to create a post route that can accept JSON data for serialization and return another JSON response. So far I created the below code but the code has some error and I am unable to solve it.

I also upload the project in github: https://github.com/devawal/akka-http-bidder

// This class will take POST JSON data and process for internal matching
case class BidRequest(id: String, imp: Option[List[Impression]], site: Site, user: Option[User], device: Option[Device])


// BidResponse protocol:
// This will return as HTTP JSON response
case class BidResponse(id: String, bidRequestId: String, price: Double, adid: Option[String], banner: Option[Banner])


trait ServiceJsonProtoocol extends DefaultJsonProtocol {
  implicit val customerProtocol = jsonFormat5(BidResponse)
}

object Bidder extends App with ServiceJsonProtoocol{
  implicit val system = ActorSystem("bid_request")
  implicit val meterializer = ActorMaterializer()
  import system.dispatcher
  import akka.http.scaladsl.server.Directives._

  // Define common HTTP entity
  def toHttpEntity(payload: String) = HttpEntity(ContentTypes.`application/json`, payload)

  //implicit val timeOut = Timeout(2 seconds)


  // Server code
  val httpServerRoute =
   pathPrefix("api" / "bid-request") {
     post {
       entity(as[requestData]){ request =>

       }
     }
  }

  Http().bindAndHandle(httpServerRoute, "localhost", 8080)
}

My request JSON is:

{"id":"XN2zZQABxJsKK0jU4QnIzw","imp":[{"id":"1","banner":{"w":300,"h":250,"pos":3,"format":[{"w":300,"h":250}]},"displaymanager":"GOOGLE","tagid":"4254117042","bidfloor":0.19,"bidfloorcur":"USD","secure":1,"metric":[{"type":"click_through_rate","value":0,"vendor":"EXCHANGE"},{"type":"viewability","value":0.80000000000000004,"vendor":"EXCHANGE"},{"type":"session_depth","value":13,"vendor":"EXCHANGE"}],"ext":{"billing_id":["71151605235"],"publisher_settings_list_id":["18260683268513888323","2151365641960790044"],"allowed_vendor_type":[79,138,144,237,238,331,342,414,445,474,485,489,523,550,566,698,704,743,745,767,776,780,785,797,828,4374,4513,4648,4651,4680,4697],"ampad":3}}],"site":{"page":"http://jobs.bdjobs.com/jobsearch.asp","publisher":{"id":"pub-5130888087776673","ext":{"country":"BD"}},"content":{"contentrating":"DV-G","language":"en"},"ext":{"amp":0}},"device":{"ua":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0","ip":"103.219.170.0","geo":{"lat":23.818607330322266,"lon":90.433006286621094,"country":"BGD","utcoffset":360},"os":"Windows","devicetype":2,"pxratio":1},"user":{"id":"CAESEGTB3gVLV019BLOZ9saadwo","data":[{"id":"DetectedVerticals","name":"DoubleClick","segment":[{"id":"5076","value":"0.8"},{"id":"960","value":"1"},{"id":"61","value":"0"},{"id":"330","value":"0.1"},{"id":"959","value":"0.1"}]}]},"at":2,"tmax":122,"cur":["USD"],"ext":{"google_query_id":"ANy-zJH36AVK9h5uCf4Z0xfyWjrBZU6M7mxGfgQE9A_qw_HahXk9khANxU7o1KDEIsfldK0DAw"}}

How can I process Input JSON and send response?

Update

I updated my route to point with case class but got error in console

val httpServerRoute =
     post {
       path("bid-request")
       entity(implicitly[FromRequestUnmarshaller[requestData]]) { request =>
         complete((dataBiddermap ? getBidderData(request)).map(
           _ => StatusCodes.OK
         ))
       }
     }

Error message:

Error:(95, 25) could not find implicit value for parameter e: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[bidder.requestData]
   entity(implicitly[FromRequestUnmarshaller[requestData]]) { request =>
Error:(95, 25) not enough arguments for method implicitly: (implicit e: akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[bidder.requestData])akka.http.scaladsl.unmarshalling.FromRequestUnmarshaller[bidder.requestData].Unspecified value parameter e.
   entity(implicitly[FromRequestUnmarshaller[requestData]]) { request =>
1
There is a lot of code here, can you cut this down to a minimal reproducible example? You need a post directive somewhere, and perhaps it is better to try a simple get endpoint first.Tim
Also, what is the error? Does it not compile, or does it compile but does it not behave as expected when you run it? How do you run it, what result did you expect, and what result did you get?Arnout Engelen
I update my code in compact version, I don't know the proper procedure to pass the request JSON data from route directive to case class and return JSON response. I compile the code but there is error as the route part is incomplete. All I need to POST my JSON data and return case class BidResponse as JSON format. Please guide me how can I do it. I followed some documentation but it create more confusionAbdul Awal
I know this is a simple task as it is all about POST a JSON to a POST directive and return specific data as JSON maybe print ID and banner w, h from POST JSON as JSON format. But I am new so I make silly mistake, please consider that way. Maybe my code structure is not correct, so can you please show me how can I process my reference JSON dataAbdul Awal

1 Answers

1
votes

I use this pattern for post requests in my server, hope this helps:

post {
  decodeRequest {
    entity(as[BidRequest]) { bidRequest =>
      val response: BidResponse = process(bidRequest)

      complete(response)
    }
  }
}

The marshalers for the request and response types are in scope.