My need is to give information about data constraints or default values to the client app that will use the API. The schema or the ALPS generated by Spring Data Rest
seems to be a good place to put this information.
But the part about documenting the API is a bit quick in the official reference documentation, and I can't find fully documented example in the community. I've tried to read the code of PersistentEntityToJsonSchemaConverter
to have a insight of the offered possibilities, but the headache arrived first.
I know there is the @Description
annotation that I can put on Entities and Properties that will change the title
field of the schema.
I know the same fields can be modified in rest-messages.properties
Is there other fields that can be modified by annotations or configuration files ? Putting default or constraints information in this description field really feels like not using it straight.
The question is almost old, I don't know if you have already found a solution.
Anywhere, you can build a completely custom ALPS profiling information if you build two custom converters that replace the converters used by Spring.
The first one needs to extends the converter org.springframework.data.rest.webmvc.alps.AlpsJsonHttpMessageConverter
.
Here a possible implementation:
public class CustomAlpsJsonHttpMessageConverter extends AlpsJsonHttpMessageConverter {
public CustomAlpsJsonHttpMessageConverter(RootResourceInformationToAlpsDescriptorConverter converter) {
super(converter);
}
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return super.canWrite(clazz, mediaType);
}
@Override
public boolean canRead(Type type, Class<?> contextClass, MediaType mediaType) {
return super.canRead(type, contextClass, mediaType);
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
Class<? extends HttpMessageConverter<?>> selectedConverterType, ServerHttpRequest request,
ServerHttpResponse response) {
return super.beforeBodyWrite(body, returnType, selectedContentType, selectedConverterType, request, response);
}
@Override
public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
return converterType.equals(AlpsJsonHttpMessageConverter.class)
|| converterType.equals(CustomAlpsJsonHttpMessageConverter.class);
}
}
The second one needs to extends the converter org.springframework.data.rest.webmvc.alps.RootResourceInformationToAlpsDescriptorConverter
.
The RootResourceInformationToAlpsDescriptorConverter
only have two public resources: the constructor and the "convert" method.
You may to overwrite every single private field/method of that class if you want to have a custom behaviour.
Pay attention that the "supports" method of your CustomAlpsJsonHttpMessageConverter
will need to matches the given "converterType" with your new CustomAlpsJsonHttpMessageConverter
class.
At that point you can customize the "convert" method of the class RootResourceInformationToAlpsDescriptorConverter
, simply ovverriding it in your CustomRootResourceInformationToAlpsDescriptorConverter
.
Finally, you have to register the two converters in the Application Context. In order to do that, you can extend the RepositoryRestMvcConfiguration
class, and in your CustomRepositoryRestMvcConfiguration
you will need to @Override
the methods "alpsJsonHttpMessageConverter()"
and "alpsConverter()"
.
Add also the @Bean
annotation in the two ovverriding custom methods, like this:
@Bean
@Override
public AlpsJsonHttpMessageConverter alpsJsonHttpMessageConverter() {
return new CustomAlpsJsonHttpMessageConverter(alpsConverter());
}
@Bean
@Override
public RootResourceInformationToAlpsDescriptorConverter alpsConverter() {
Repositories repositories = repositories();
PersistentEntities persistentEntities = persistentEntities();
RepositoryEntityLinks entityLinks = entityLinks();
MessageSourceAccessor messageSourceAccessor = resourceDescriptionMessageSourceAccessor();
RepositoryRestConfiguration config = config();
ResourceMappings resourceMappings = resourceMappings();
return new CustomRootResourceInformationToAlpsDescriptorConverter(associationLinks(), repositories, persistentEntities,
entityLinks, messageSourceAccessor, config, objectMapper(), enumTranslator());
}
So you can have a completely custom ALPS, if you need.
I have tried this solution to build custom profiling links, and it works perfectly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With