#837 - Added section on registering a custom media type.
This commit is contained in:
@@ -56,4 +56,89 @@ Since the purpose of the `CurieProvider` API is to allow for automatic curie cre
|
||||
[[mediatypes.custom]]
|
||||
== Registering a custom media type
|
||||
|
||||
TODO
|
||||
Spring HATEOAS allows to integrate support for custom media types through a set of SPIs, that third parties can implement.
|
||||
The building blocks of an such an implementations are:
|
||||
|
||||
1. Some form of Jackson ObjectMapper customization. In its most simple case that's a Jackson `Module` implementation.
|
||||
2. A `LinkDiscoverer` implementation so that the client side support is able to detect links in representations generated.
|
||||
3. Some configuration infrastructure that will allow Spring HATEOAS to find the custom implementation and pick up its configuration.
|
||||
|
||||
[[mediatypes.custom.configuration]]
|
||||
=== Custom media type configuration
|
||||
|
||||
Custom media type implementations are picked up through Spring's `SpringFactories` mechanism, similar to the Java `ServiceLoader` API.
|
||||
Each media type implementation needs to ship with a `spring.factories` in `META-INF` containing an implementation class entry for the `org.springframework.hateoas.config.MediaTypeConfigurationProvider` key:
|
||||
|
||||
.An example `MediaTypeConfigurationProvider` declaration
|
||||
====
|
||||
[source]
|
||||
org.springframework.hateoas.config.MediaTypeConfigurationProvider=\
|
||||
com.acme.mymediatype.MyMediaTypeConfigurationProvider
|
||||
====
|
||||
|
||||
That implementation class could then look as follows:
|
||||
|
||||
.An example `MediaTypeConfigurationProvider` implementation in `META-INF/spring.factories`
|
||||
====
|
||||
[source,java]
|
||||
----
|
||||
class MyMediaTypeConfigurationProvider
|
||||
implements MediaTypeConfigurationProvider {
|
||||
|
||||
@Override
|
||||
public Class<? extends HypermediaMappingInformation> getConfiguration() {
|
||||
return MyMediaTypeConfiguration.class; <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsAny(Collection<MediaType> mediaTypes) {
|
||||
return mediaTypes.contains(MediaTypes.HAL_JSON); <2>
|
||||
}
|
||||
}
|
||||
----
|
||||
The configuration class needs to have a default constructor and expose two methods:
|
||||
|
||||
<1> A method returning a Spring configuration class that will be included in the application bootstrap when Spring HATEOAS is activated (either implicitly via Spring Boot auto-configuration or via `@EnableHypermediaSupport`).
|
||||
<2> A callback method that will get the application selected media types to activate passed. This allows the media type implementation to control, when it it will be activated.
|
||||
====
|
||||
|
||||
The configuration class has to implement `HypermediaMappingInformation`. It could look as simple as this:
|
||||
|
||||
====
|
||||
[source, java]
|
||||
----
|
||||
@Configuration
|
||||
class MyMediaTypeConfiguration implements HypermediaMappingInformation {
|
||||
|
||||
@Override
|
||||
public List<MediaType> getMediaTypes() {
|
||||
return MediaType.parse("application/vnd-acme-media-type") <1>
|
||||
}
|
||||
|
||||
@Override
|
||||
public Module getJacksonModule() {
|
||||
return new Jackson2MediaTypeModule(); <2>
|
||||
}
|
||||
|
||||
@Bean
|
||||
MyLinkDiscoverer myLinkDiscoverer() {
|
||||
return new MyLinkDiscoverer(); <3>
|
||||
}
|
||||
}
|
||||
----
|
||||
<1> The configuration class returns the media type it wants to get Spring MVC / Spring WebFlux support set up.
|
||||
<2> It overrides `getJacksonModule()` to provide custom serializers to create the media type specific representations.
|
||||
<3> It also declares a custom `LinkDiscoverer` implementation for client side support.
|
||||
====
|
||||
|
||||
The Jackson module usually declares `Serializer` and `Deserializer` implementations for the representation model types `RepresentationModel`, `EntityModel`, `CollectionModel` and `PagedModel`.
|
||||
In case you need further customization of the Jackson `ObjectMapper` (like a custom `HandlerInstantiator`), you can alternatively override `configureObjectMapper(…)`.
|
||||
|
||||
[[mediatypes.custom.recommendation]]
|
||||
=== Recommendations
|
||||
|
||||
The preferred way to implement media type representations is by providing a type hierarchy that matches the expected format and can be serialized by Jackson as is.
|
||||
In the `Serializer` and `Deserializer` implementations registered for `RepresentationModel`, convert the instances into the media type specific model types and then lookup the Jackson serializer for those.
|
||||
|
||||
The media types supported by default use the same configuration mechanism as third party implementations would.
|
||||
So it's worth studying the implementations in https://github.com/spring-projects/spring-hateoas/tree/master/src/main/java/org/springframework/hateoas/mediatype[the `mediatype` package].
|
||||
|
||||
Reference in New Issue
Block a user