Hide ID on POST in RequestBody, but return ID on created

2.5k views Asked by At

For example I have a bean

public class Order
{
    int orderID;
    String name;
}

And I have a POST operation

@ApiOperation(value = "Insert a new order", response = Order.class)
@RequestMapping(value = "/addOrder", method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
@ResponseBody
public Order addOrder(@Valid @RequestBody Order order)
{   
    //Set random id here
    order.id = 'xxxxx';     
    Order o = orderService.insertOrder(order);        
    return o;
}

And in Swagger I have the following:

swagger_img

So my question is, how do I hide id on POST but show ID on GET? Or should I add a description saying that even if you choose to add an ID it wont do anything and just return my random id? Just like in Kubernetes (uid)

And properties like read-only in @ApiModelProperty will solve anything?

1

There are 1 answers

3
sisyphus On BEST ANSWER

A simple approach is to split your bean in two - one for creating a new object, and another one which extends that for data about an existing object.

e.g.

public class IncompleteOrder {
    String name;
}

public class ExistingOrder extends IncompleteOrder {
    int id;
}

Then have your POST method take an object of IncompleteOrder and return one of ExistingOrder. I'd also delegrate responsibility for assigning a random order id to the underlying service...

public ExistingOrder addOrder(@Valid @RequestBody IncompleteOrder order) {
        ExistingOrder o = orderService.insertOrder(order);        
        return o;
 }

The same thing could be achieved by having two completely separate classes with no inheritance relationship, which would probably be appropriate if there was a significant divergence between the information needed to create a new order from the information which is on an existing order.

An alternative is to ask what the id is actually for - why are your clients getting integer id's for anything? Ideally, if they want any information about the order they should be querying the API for the resource, and to do that they need the URI of the order rather than the integer id. So external services communicating about an order should be passing the URIs back and forth rather than ids. Perhaps you could encourage your clients to communicate with each via the URI you return in the Location header from your POST request? Then you could do away with exposing the id on your response and have a purely symmetric request / response body.