0

I have Spring Boot REST api which returns JSON object like this -

{
  "id": "1"
  "timestamp": "2020-08-03T08:49:02.679+00:00"
  "message": "hello"
}

This is directly derived from @Entity like this -

fun getMessage(id: Long) = messageRepository.findById(id)

Here, Spring boot automatically converts the response into JSON. However, I want to add another key-value pair in the getMessage() function. Similar to this - How can I add a key/value pair to a JavaScript object? but in Java/ Kotlin.

How do I do that?

krtkush
  • 1,378
  • 4
  • 23
  • 46

2 Answers2

3

Maybe you could create another Model for that and create an extension to convert into the new model.

data class Message(
    val id: Int,
    val timestamp: String, 
    val message: String   
)

data class MessageWithMoreInfo(
    val id: Int,
    val timestamp: String, 
    val message: String,
    val info: String   
)

fun Message.toMessageWithMoreInfo(val info: String) = MessageWithMoreInfo(
    id,
    timestamp,
    message,
    info
)
Luciano Ferruzzi
  • 1,042
  • 9
  • 20
1

You won't be able to replicate javascript's way of injecting keys & values into objects, as Java (and Kotlin) is a statically typed language.

Spring's conversion to Json isn't magic. Most likely it will serialize your Entity with an Object Mapper (Jackson or Gson).

Now, you can work around this limitation in many ways (some are better than others), Luciano's answer being one of the best ones.

But, depending on what you are injecting into your entity and how your project design is defined, you could do exactly what javascript does by using the Object Mapper provided by the spring context and convert your Entity into a Map<String, Any>:

@Service
class AServiceImpl(
        private val repository: ARepository,
        // autowires the objectMapper
        private val objectMapper: ObjectMapper
) : AService {

    override fun getMessage(id: Long): Map<String, Any>{
        val entity = repository.findById(id)
        // here you have something more like a javascript Object 
        val map: MutableMap<String, Any> = objectMapper.convertValue(entity)
        // so you can add key/value pairs to it
        map["something"] = "some_value"
        // but you will need to change the method signature 
        return map
    }
}

Remember: passing maps is kinda dangerous, you lose many of the benefits Java/Kotlin brings :)