Add created date time to a REST API using Swagger

Viewed 446

I have a couple of APIs and using springfox-swagger for API documentation. I have a requirement to add the creation date to the respective API. How can I achieve this using swagger. I don't need any API versioning.

Ex:

@ApiOperation(value = "Creates a new user and returns the created user.")
    @PostMapping(/user)
    public ResponseEntity<UserDto> createUser(@RequestBody UserDto userDto) {
        User user =userService.create(userDto);
        return new ResponseEntity<>(UserMappers.USER_ENTITY_TO_DTO.apply(user),HttpStatus.CREATED);
    }

In the above example, I want to add the creation date of /user so that I can trace the creation date.

1 Answers

In my project I have a similar requirement. As a solution I have created a custom annotation (for marking the endpoint) and wrote a plugin (for updating the API description).

Option #1

  • @ApiSince annotation:

    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    public @interface ApiSince {
        String value() default "";
    }
    
  • ApiSincePlugin plugin:

    @Component
    public class ApiSincePlugin implements OperationBuilderPlugin {
    
        private final DescriptionResolver resolver;
    
        @Autowired
        public ApiSincePlugin(DescriptionResolver resolver) {
            this.resolver = resolver;
        }
    
        @Override
        public void apply(OperationContext context) {
    
            final String sinceTemplate = "### Since %s%n%n%s";
            String notes = "";
            Optional<ApiOperation> apiOperationOptional = context.findAnnotation(ApiOperation.class);
            if (apiOperationOptional.isPresent()) {
                notes = apiOperationOptional.get().notes();
            }
            String finalNotes = notes;
            Optional<ApiSince> apiSinceOptional = context.findAnnotation(ApiSince.class);
            if (apiSinceOptional.isPresent()) {
                finalNotes = String.format(sinceTemplate, apiSinceOptional.get().value(), notes);
            }
            context.operationBuilder().notes(resolver.resolve(finalNotes));
        }
    
        @Override
        public boolean supports(DocumentationType type) {
            return true;
        }
    }
    
  • @ApiSince in action:

    @ApiSince(value = "2019-10-31")
    @PostMapping(value = "/login")
    @ApiOperation(value = "Authenticate user", nickname = "login", notes = "your API description")
    @ResponseStatus(HttpStatus.OK)
    @ApiResponses(value = {
        @ApiResponse(code = 200, response = LoginResponse.class, message = HTTP_200_OK),
        ...
    })
    @ResponseBody
    ResponseEntity<LoginResponse> login(...);
    


If you don't want do add it in the description but as an extra JSON attribute then take a look at this solution: Custom Operation Builder Plugin .

Option #2

  • @ApiSince annotation (code same as above)
  • ApiSincePlugin plugin:

    @Component
    public class ApiSincePlugin implements OperationBuilderPlugin {
    
        @Override
        public void apply(OperationContext context) {
            Optional<ApiSince> annotation = context.findAnnotation(ApiSince.class);
            if (annotation.isPresent()) {
                String value = annotation.get().value();
                ObjectVendorExtension extention = new ObjectVendorExtension("x-since");
                extention.addProperty(new StringVendorExtension("value", value));
                context.operationBuilder().extensions(Collections.singletonList(extention));
            }
        }
    
        @Override
        public boolean supports(DocumentationType documentationType) {
            return true;
        }
    }
    
  • Activate extensions in the Swagger UI:

    @Bean
    UiConfiguration uiConfig() {
        return UiConfigurationBuilder
                .builder()
                .showExtensions(true)
                ...
                .build();
    }
    
  • @ApiSince in action (code same as above):

Related