In this post, we'll discuss how to receive data in a REST end-point in multiple formats. Say you have an endpoint for adding customers, as below:

POST /customers

There could be two types of customers, INDIVIDUAL and ORGANIZATION. For individuals, the body would have the following format:

{
  type: "INDIVIDUAL",
  firstName: "Sanjay",
  lastName: "Patel"
}

For orgnizations, it'd be as below:

{
  type: "ORGANIZATION",
  name: "naturalprogrammer.com"
}

In essence, there's a type field, based on which the format varies.

So, how to code that in Spring Boot and MVC?

Technically, coding two different end-points for the two types would be simplest. But in real-world, API designers prefer a single end-point for this kind of requirements. You could use some sophisticated way to support that, like using RequestMappingHandlerMapping and overriding the getCustomMethodCondition method. But a simpler way would be to receive the request data as string, and first parse that into a POJO having only the type field. That will tell you the type of the customer. Then, you could re-parse the string into the respective type. Something like this:

@RestController
@RequestMapping("/customers")
public class CustomerController {
    @Autowired
    private ObjectMapper objectMapper;
    @Autowired
    private CustomerService customerService;
    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public Customer createCustomer(@RequestBody String customerStr) {
        Type type = objectMapper.readValue(customerStr, Type.class);
        if (type.getType().equals(INDIVIDUAL)) {
            IndividualCustomer customer = objectMapper.readValue(customerStr, IndividualCustomer.class);
            return customerService.createIndividualCustomer(customer);
        } 
        ...
    }
}

Data validation can be done in the service layer, as discussed in this post.