orbfish
orbfish

Reputation: 7731

What's a good pattern or style in REST Resource classes to encapsulate error handling?

I've run into this pattern several times. In pseudo-code:

public class BlahResource { if (thisError) buildResponse(BAD_REQUEST); if (thatError) buildResponse(CONFLICT); ... doSomething(); return buildResponse(SUCCESS); }

Doesn't look too bad, but when you have a million error conditions to handle, too much business logic accretes into the Resource class and the noise quickly overwhelms the story of what the code is actually doing.

Since in a resource the error conditions are returning something, an exception thrown from a service doesn't seem right to me. And a status object encapsulating different combinations of return conditions and setups seems like overkill.

Is there something obvious I'm missing in how this can be coded in a logical, clear way? Possibly something functional/Guava/lambda-based that I'm missing, or just a regular OO solution.

Upvotes: 1

Views: 106

Answers (1)

Master Slave
Master Slave

Reputation: 28519

There's a complete JSR-349 Bean Validation specification addressing these concerns

From the specification goals

Validating data is a common task that occurs throughout an application, from the presentation layer to the persistence layer. Often the same validation logic is implemented in each layer, proving to be time consuming and errorprone. To avoid duplication of these validations in each layer, developers often bundle validation logic directly into the domain model, cluttering domain classes with validation code that is, in fact, metadata about the class itself. This JSR defines a metadata model and API for JavaBean validation. The default metadata source is annotations, with the ability to override and extend the meta-data through the use of XML validation descriptors.

The hibernate-validator is the reference implementation, but just note that the implementation is not tied to any tier (nor web nor the persistence tier)

Going back to your resource code, this would mean that, by utilizing the custom constraints, your Resource would look something like

public class BlahResource {
  @CheckBadRequest
  @CheckConflict
  private field
  ...
}

when the validation fails, the errors are stored inside ConstraintViolation that you can obtain through Validator interface. Those are the central points around which you should build your error handling mechanism, again a pseudo

Set<Constraintviolation<Resource>> violations = validator.validate(Resource);

Upvotes: 2

Related Questions