-
Notifications
You must be signed in to change notification settings - Fork 471
Collections not embedded with HAL compatible vendor specific media type #1253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
What's the client sending as |
The client is sending I also tried adding Client explicitly requesting for edit: I'm actually running this now from |
Can you post your custom media type? |
public class CustomHypermediaType implements HypermediaMappingInformation {
public static final MediaType FRODO_MEDIATYPE = MediaType.parseMediaType("application/frodo+json");
@Override
public List<MediaType> getMediaTypes() {
return Collections.singletonList(FRODO_MEDIATYPE);
}
@Override
public Module getJacksonModule() {
return new Jackson2HalModule();
}
} |
And that class is registered as an |
The behavior you describe smells like what happens when you request a mediatype that isn't registered. Spring Framework and it's default converters will bypass HAL and end up with a default handler that responds to Hence, it implies your |
Sure, the bean is registered right here in https://github.com/spring-projects/spring-hateoas/blob/master/src/test/java/org/springframework/hateoas/config/CustomHypermediaWebMvcTest.java. I am not running this from my own code. I am running the test code from this repository, with the modifications described above. |
Okay, I missed that you were tinkering inside our code. Digging in, I saw what you saw. Which intrigued me. I tried Basically, you need this: public class CustomHypermediaType implements HypermediaMappingInformation {
public static final MediaType FRODO_MEDIATYPE = MediaType.parseMediaType("application/frodo+json");
/**
* {@link MediaType}s this hypermedia can handle.
*/
@Override
public List<MediaType> getMediaTypes() {
return Collections.singletonList(FRODO_MEDIATYPE);
}
/**
* Copy the incoming {@link ObjectMapper} and change it's output format along with disabling failure on unknown
* properties.
*/
@Override
public ObjectMapper configureObjectMapper(ObjectMapper mapper) {
mapper.registerModule(getJacksonModule());
mapper.setHandlerInstantiator(new Jackson2HalModule.HalHandlerInstantiator(new EvoInflectorLinkRelationProvider(),
CurieProvider.NONE, MessageResolver.DEFAULTS_ONLY));
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
mapper.enable(SerializationFeature.INDENT_OUTPUT);
return mapper;
}
@Override
public Module getJacksonModule() {
return new Jackson2HalModule();
}
} That is the proper way to register HAL support. Once you do that, of course, it breaks the existing test case, because BTW, the proper way to declare that aggregate root is: @GetMapping("/employees")
public CollectionModel<EntityModel<Employee>> findMany() {
List<EntityModel<Employee>> employees = new ArrayList<>();
employees.add(new EntityModel(new Employee("Frodo Baggins", "ring bearer"),
linkTo(methodOn(EmployeeController.class).findOne()).withSelfRel()));
return new CollectionModel(employees, linkTo(methodOn(EmployeeController.class).findMany()).withSelfRel());
} Cool? |
Ah, I was basically missing the part with the handler instantiator. I think I need to take a closer look at those handler instantiators, never played with them before. I actually wrote it a bit differently in the fork to write a separate test case for Thanks for taking the time to check it. |
Seems like I ran into another problem with |
For reference (originally commented on #1259): While I think the route via a custom media type registration is a decent workaround, it's not what it was designed for initially and going down that route shouldn't be necessary if all you want to do is register an media type name alias to The concrete media types a media type implementation is registered under is already obtained via WDYT? |
That does make a lot of sense since the intent was indeed to just register a media type name alias for |
I am currently running into the same issue, as i also want to apply API versioning via custom media types. Are you planning to integrate the simple solution mentioned by @odrotbohm? |
HalConfiguration now exposes a withMediaType(…) that adds custom media types in front of the default of `application/hal+json`. This allows developers to use a project specific media type which is treated like it being HAL in the first place.
This is in place now. Use |
@odrotbohm Would it be possible to support this in Thank you in advance. |
Sure thing, I've filed and fixed #1591. |
That was quick 😃 Thank you so much! 🙌🏼 |
I ran into this same issue and it broke my brain, only to find this thread somewhere in some sketchy part of our code ^^. We fixed this issue by autowiring whatever LinkRelationProvider is used by HATEOAS, which solved the problem. The LinkRelationProvider of Spring is able to both work with and without the So in your configuration file, make sure to autowire a LinkRelationProvider like this (Kotlin Code)
and then replace the EvoInflectorProvider with this linkRelationProvider:
|
I have been searching for information about vendor specific media types that are HAL compatible, and found several issues related to this. Apparently it is possible to easily add custom media types.
However, I'm unable to make returned collections to be embedded.
Taking the
CustomHyperMediaWebMvcTest
as an example, and adding a collection:This will return:
Making the controller endpoint explicitly produce
application/frodo+json
has no effect either. However, making the endpoint produceapplication/hal+json
works as expected:Is there something fundamental I am missing about the configuration, or is this an actual bug?
The text was updated successfully, but these errors were encountered: