1

Assuming there is a REST Controller with an endpoint that accepts a single object in the body:

@PostMapping("/ExampleObjects")
void mapping(@RequestBody ExampleObject object){ ....

If one would want to add the ability to accept an array under the same endpoint like this:

@PostMapping("/ExampleObjects")
void mapping(@RequestBody ExampleObject[] objects){ ....

Is there a way to implement the new functionality with the given design and without breaking existing users?

1
  • In general, array-POST is a bad pattern because it does not conform to the standard HTTP principles. For example, what happens with partial success? You can't return multiple status codes. You also can't return multiple Location headers. Instead, it's almost always preferable to just make multiple POST requests in sequence. Commented Jan 2, 2021 at 21:42

4 Answers 4

3

That should help you.

application.properties:

spring.jackson.deserialization.accept-single-value-as-array=true

controller:

@PostMapping("/ExampleObjects")
void mapping(@RequestBody List<ExampleObject> objects){ ....
Sign up to request clarification or add additional context in comments.

Comments

0

How about having the first endpoint called "/ExampleObject" instead, seeing as it appears to be singular?

3 Comments

Renaming the endpoints does indeed work but I was just curious whether there is an elegant way to avoid this.
I've updated the answer to make it clearer why I suggest renaming it that
I definitely understand your reasoning and would usually agree. However the exact naming and API design is not my focus here. This was merely an example for clarification and not real code. The goal of this question is to learn whether an unified handling of singular objects and arrays is easily possible purely in theory. I'll try to edit my question to make this clearer
0

It's good practise to keep your API endpoints as simple as possible, as consistent as possible (between different endpoints in the single API), and as error-tolerant as possible.

Instead of an array, you'd want to use a generic List<ExampleObject> in any case.

You could just implement the list version of the method, call that method with a list that only contains a single instance. You'd want to think about the consistency part of the equation a little bit. What kinds of different endpoints will you be implementing in your API. Would this solution fit most of those use cases?

Go with the solution that results with the least surprises to your API users.

1 Comment

I edited the question to make my intent clearer. Sorry for the confusion
0

Currently something like Jackson is doing the parsing from HTTP request body to ExampleObject automatically for you.

You could do the parsing in your code and decide during parsing, if it is an instance of ExampleObject or ExampleObject[]. Therefore you would have one method with this signature:

@PostMapping("/ExampleObjects")
void mapping(@RequestBody String objectOrArray){ 
    // code to parse String into ExampleObject or ExampleObject[] ...

This should handle your issue, but a better API design would be having 2 different endpoints / URLs.

1 Comment

Thank you this is probably the most straightforward solution. Can't believe I didn't think of that. I'm not too worried about design as it was a purely theoretical question that came up while messing around

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.