users@jersey.java.net

[Jersey] Best practices for returning error information as JSON?

From: Tauren Mills <tauren_at_groovee.com>
Date: Mon, 14 Feb 2011 15:14:30 -0800

I'm using Hibernate Validator to verify that JSON input is validated before
sending it to my business layer. If this validation process fails, it
results in a set of violations with messages I would like to send back to
the user. I don't know of any best practices, so I'm looking for
suggestions.

@POST
public Response createEvent(EventDTO dto) {
  try {
    Event event = eventService.createEvent(dto);
    URI uri =
uriInfo.getAbsolutePathBuilder().path(event.getId().toString()).build();
    return Response.created(uri).entity(event).build();
  } catch (ValidationException e) {
    Set<ConstraintViolation<EventDTO>> violations = e.getViolations();
    return
Response.status(Response.Status.BAD_REQUEST).entity(violations).build();
  }
}

The above .entity(violations) doesn't actually work right now as nothing
knows how to map the set of ConstraintViolations to JSON. But I'm putting it
there to illustrate the direction I'm going. In my service layer:

public Event createEvent(EventDTO dto) throws ValidationException {
  ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
  Validator validator = factory.getValidator();
  Set<ConstraintViolation<EventDTO>> violations = validator.validate(dto);
  if (violations.size() > 0) {
    throw new ValidationException("Event details are invalid", violations);
  }
  // Do other stuff to create and save a new event
  return newEvent;
}

An example POJO:

public class EventDTO implements Serializable {
  @Size(min=4, max=25)
  private String title;
  @Future
  private Date date;
  @Email
  private String organizer;
}

So, when a validation error happens, I'm sending back a BAD_REQUEST response
code. Perhaps there is a better code for validation errors.

I'd like to also send back a JSON object that describes the violations. Is
there a standard format for this object, or any best practices? I'm
planning to create a pojo, such as ValidationViolations that contains all
the I18N messages from within each ConstraintViolation. The methods I would
use to build this are shown here:
http://docs.jboss.org/hibernate/validator/4.2/reference/en-US/html/validator-usingvalidator.html#d0e651

But is there a recommended format for error payload? What kind of
information is typically sent back? How much information is useful? For
instance, something like this would give me lots of information, but it
might be too verbose:

{
  "envelopeVersion":"1.0",
  "code": 400,
  "status": "Bad Request",
  "subCode": 23,
  "message": "Event details are invalid",
  "count": 2,
  "data": [
    {
      "root": "event",
      "property":"date",
      "template":"{javax.validation.constraints.Future.message}",
      "message":"must be in the future",
      "invalidValue":"2010-12-1T08:00:00Z"
    },
    {
      "root": "event",
      "property":"title",
      "template":"{javax.validation.constraints.Size.message}",
      "message":"size must be between 4 and 25",
      "invalidValue":"Go"
    }
  ]
}

Thanks for your thoughts!
Tauren