0

I need to return a json response in camelCase with finatra but it is in snake_case by default. From what I found so far, I need to use ObjectMapper, but I can't understand where do I pass it once I create it. An example would be very helpful. Here is what I have:

import com.twitter.finagle.http.Request
import com.twitter.finatra.http.Controller

class myTargetingController extends Controller {
    val endpoint = "http://....."

    get(s"$endpoint/?") { request: Request =>
        // what do I do with it?
        // val objectMapper = ScalaObjectMapper.builder.camelCaseObjectMapper 
        response.ok.json(myObject)
    }
}

==================================================================

import com.twitter.finagle.{Service, SimpleFilter}
import com.twitter.finagle.http.{ Request, Response}
import com.twitter.finatra.http.routing.HttpRouter
import com.twitter.finatra.http.{HttpServer}
import com.twitter.finatra.http.filters.CommonFilters
import com.twitter.util.Future

object MyServerApp extends MyServer

class MyServer extends HttpServer {
override protected def configureHttp(router: HttpRouter) {
    router
        .filter[CommonFilters]
        .add[CorsFilter, MyController]
    }
}

P.S. I am very-very new to Scala

chibis
  • 658
  • 2
  • 12
  • 22
  • You can not use that in the end point like that. You need to wrap the logic in a ```TwitterModule``` and bind that module to your server so that it gets injected properly. It might just be easier using ```ScalaObjectMapperModule``` overall – sinanspd Apr 27 '20 at 23:12
  • could you please give an example. As I said I am very new to Scala and there are a lot of unknowns in what you said :) – chibis Apr 27 '20 at 23:32
  • I need to boot up one of my old finatra projects to make sure my example works, I don't want to give you code that I haven't verified. So you will have to wait until I get home. Meanwhile familiarize yourself with Finatra Modules please. It will clarify all those "unknowns" http://twitter.github.io/finatra/user-guide/getting-started/modules.html – sinanspd Apr 27 '20 at 23:38

1 Answers1

0

Following up from the comments

Define a custom ObjectMapperModule

class CamelCaseModule extends ScalaObjectMapperModule {

    override val propertyNamingStrategy: PropertyNamingStrategy =
      new PropertyNamingStrategy.UpperCamelCaseStrategy

    override def additionalMapperConfiguration(mapper: ObjectMapper): Unit = {
      mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true)
 }
}

Override the default Jackson module for your server

override def jacksonModule = new CamelCaseModule

Make sure you have

"com.twitter" %% "finatra-jackson" % yourFinatraVersion % "test"

in your build.sbt

And that you import

import com.fasterxml.jackson.databind.{DeserializationFeature, Module, ObjectMapper, PropertyNamingStrategy}
import com.twitter.finatra.jackson.modules.ScalaObjectMapperModule

Tested it locally and it seems to work Hope this helps

sinanspd
  • 2,589
  • 3
  • 19
  • 37
  • thank you so much for your time and effort. Unfortunately I don't understand where should this go. I have edited my post to include more of my current set up. Please, let me know if I need to add more info. Thank you! – chibis Apr 28 '20 at 01:08
  • @chibis CamelCaseModule can go anywhere as long as ```MyServer``` can reference it, the second line ```jacksonModule``` will go in ```MyServer``` before ```configureHttp``` – sinanspd Apr 28 '20 at 01:10
  • Updated the answer with necessary imports as well @chibis – sinanspd Apr 28 '20 at 01:13
  • I think I got it. I put it in `override def jacksonModule: Module = new CamelCaseModule` in `myServer` class. Had to change `override val propertyNamingStrategy: PropertyNamingStrategy = PropertyNamingStrategy.LOWER_CAMEL_CASE` to match my requirements. And it works. Thank you so, so very much @sinanspd!!!! Spent entire day today trying to figure it out – chibis Apr 28 '20 at 01:18