I'm designing JAX-RS APIs.
POST /myentities
PUT /myentities/{myentityId}
I did like this.
@PUT
@Path("/{myentityId: \\d+}")
@Consumes(...)
@Transactional
public Response updateMyentity(
@PathParam("myentityId") final long myentityId,
final Myentity myentity) {
if (!Objects.equal(myentitiyId, myentity.getId())) {
// throw bad request
}
entityManager.merge(myentity);
return Response.noContent().build();
}
I suddenly get curious and questioned to my self.
When a client invokes following request
PUT /myentities/101 HTTP/101
Host: ..
<myentity id=101>
</myentity>
Is it possible that the request is processed even if there is no resource identified by 101
?
I ran a test.
acceptEntityManager(entityManager -> {
// persist
final Device device1 = mergeDevice(entityManager, null);
entityManager.flush();
logger.debug("device1: {}", device1);
assertNotNull(device1.getId());
// remove
entityManager.remove(device1);
entityManager.flush();
assertNull(entityManager.find(Device.class, device1.getId()));
// merge again, with non existing id
final Device device2 = entityManager.merge(device1);
entityManager.flush();
logger.debug("device2: {}", device2);
});
I found that second merge works and a new id assigned.
Is this normal? Shouldn't EntityManager#merge
deny the operation?
Is it mean that any client can attack the API by calling
PUT /myentities/<any number>
?