backstopper icon indicating copy to clipboard operation
backstopper copied to clipboard

add ApiErrorValue annotation

Open tsarenkotxt opened this issue 4 years ago • 1 comments

Added and implemented @ApiErrorValue annotation, ~~without changing existing classes~~, fully backward compatible, 100% test coverage, added javaDoc, added sample module. (minor changes were added to ReflectionBasedJsr303AnnotationTrollerBase)

pros:

  1. easy to use
  2. fail-fast, at compile time
  3. supports default messages &ValidationMessages.properties (without classpath scanning/reflection)

Overview: Simple model class showing JSR 303 Bean Validation integration in Backstopper using @ApiErrorValue, that provides the ability to autoconfigure ProjectApiErrors with ApiErrors.
It can also be used with already existing ProjectApiErrors and ApiErrors.

process at compile time and registers the API errors at runtime:

public class SampleModel {

    @ApiErrorValue
    @NotBlank
    public String foo;

    @ApiErrorValue(errorCode = "BLANK_BAR", httpStatusCode = 400)
    @NotBlank(message = "bar should not be blank")
    @Pattern(regexp = "bar", message = "should match {bar}")
    public String bar;
    // -- SNIP -- 
}

the response to an empty request will be as follows:

{
 "error_id": "c6bbec89-c39a-4164-9155-fd8e1c1a5cbc",
 "errors": [
   {
     "code": "INVALID_VALUE",
     "message": "may not be empty",
     "metadata": {
       "field": "foo"
     }
   },
   {
     "code": "BLANK_BAR",
     "message": "bar should not be blank",
     "metadata": {
       "field": "bar"
     }
   }
 ]
}

the response to the request with an empty foo and an invalid bar will be as follows:

{
  "error_id": "d3d5d6d9-af31-48bf-96a7-7d91cff29cd5",
  "errors": [
    {
      "code": "INVALID_VALUE",
       "message": "may not be empty",
      "metadata": {
        "field": "foo"
      }
    },
    {
      "code": "BLANK_BAR",
      "message": "should match {bar}",
      "metadata": {
        "field": "bar"
      }
    }
  ]
}

Modules structure:

  • backstopper-annotation-post-processor - implemented: small library to process @ApiErrorValue annotation.
  • backstopper-core - added: finds @ApiErrorValue metadata.
  • backstopper-spring-web - added: registers ProjectApiErrors with ApiErrors.
  • backstopper-reusable-tests - added: @ApiErrorValue support
  • sample-spring-boot-with-apierrorvalue-annotation - implemented: sample using @ApiErrorValue.

Flow:

  1. Compile time:
    ApiErrorValueProcessor.process() =>
    -> ElementDetailsScanner.scan()
    -> ApiErrorValueProcessor.resolve()
    -> ApiErrorValueProcessor.write()
  2. Runtime:
    ProjectApiErrorsBeanPostProcessor.process() =>
    -> AutoGeneratedApiErrorService.find()
    -> ApiErrorValidationMessagesMapper.map()
    -> AutoConfiguredProjectApiErrorsBuilder.build()

currently supported Spring 4.x/5.x, Spring Boot 1.x/2.x, but it can be extended to other frameworks.

I would recommend you read @ApiErrorValue javaDoc before reviewing.

tsarenkotxt avatar Apr 15 '20 23:04 tsarenkotxt