I have a Spring REST service (written in Groovy; although that shouldn't matter) that exposes a secured endpoint like so:
class AppData {
String id
String payload
String fizzbuzz
}
@RequestMapping(method=RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody AppResponse onAppData(@RequestBody AppData appData) {
// Does some processing on appData and then saves
// its 'payload' field to a MongoDB
}
And this works perfectly fine when it receives JSON of the following form:
{
"id" : "12345",
"payload" : "Please save me to a MongoDB",
"fizzbuzz" : "wakka wakka"
}
I'm using Jackson to handle JSON serialization here.
The problem is that I now want the payload
property to be true JSON, not a String. So I want to be able to send the endpoint something like this:
{
"id" : "12345",
"payload" : {
"foo" : 24,
"bar" : false,
"whistlefeather" : "Yes of course"
},
"fizzbuzz" : "wakka wakka"
}
And have the payload properly saved off to MongoDB. But here's the catch:
Lots of different teams (potentially hundreds) are going to be sending this endpoint AppData
, and all of their payloads are going to look completely different (each team has different payloads they want to send me and have saved in MongoDB). And I don't want to have to write a new endpoint and AppData
subclass for each new team I onboard (and thus expose this endpoint to).
Is there any way I can:
- Keep my endpoint exactly the way it is; but
- Allow the
AppData#payload
property to accept JSON in any form?
Keeping my code exactly the way it is, if I send a JSON message where the payload
is also JSON (and isn't a string), Spring just returns a 400 with an empty response body. This is happening because Spring expects payload
to be a String, but sees that its a JSON object.
Any ideas on what I can do inside the AppData
class to handle this, or any notions of what the best practice is here?
Use a JsonNode as the type for the payload:
Output:
Note that to get back a JSON string for the payload, you shouldn't use toString() as in the above example. You should use
objectMapper.writeValueAsString(payload)
.You can try using a Map, i don't know what it is in Groovy, but this would be the structure in Java.