Skip to content

Enabling hypermedia disables all of WebFlux's default codecs #1061

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

Closed
wilkinsona opened this issue Sep 1, 2019 · 5 comments
Closed

Enabling hypermedia disables all of WebFlux's default codecs #1061

wilkinsona opened this issue Sep 1, 2019 · 5 comments
Assignees
Labels
Milestone

Comments

@wilkinsona
Copy link
Member

If I @EnableHypermediaSupport, all of the default server codes are lost:

As far as I can tell, this makes Spring HATEOAS difficult to use in a WebFlux application that doesn't solely contain HATEOAS-based endpoints. It's also a significant departure from using HATEOAS with Spring MVC where the Web MVC customisations are additive.

@gregturn
Copy link
Contributor

gregturn commented Sep 3, 2019

Okay, this was originally put in because something about the order of custom registered mediatype handlers and the defaults didn't work right. I'm happy to report that appears to no longer be an issue. Flipping to true causes almost all test cases to pass.

The one failing test case is where HAL is registered, but a request for UBER is made. This was originally coded to fail with a 400 HTTP status code.

Switching to true causes it to return an HTTP 200 status code:

@Configuration
@EnableWebFlux
static abstract class BaseConfig {

	@Bean
	TestController testController() {
		return new TestController();
	}
}

@EnableHypermediaSupport(type = HAL)
static class HalWebFluxConfig extends BaseConfig {}
@GetMapping
RepresentationModel<?> root() {

	RepresentationModel<?> root = new RepresentationModel<>();

	root.add(new Link("/").withSelfRel());
	root.add(new Link("/employees").withRel("employees"));

	return root;
}
@Test
void callingForUnregisteredMediaTypeShouldFail() {

	setUp(HalWebFluxConfig.class);

	this.testClient.get().uri("/").accept(MediaTypes.UBER_JSON) //
			.exchange() //
			.expectStatus().isOk() //
			.returnResult(String.class) //
			.getResponseBody() //
			.as(StepVerifier::create) //
			.expectNextMatches(s -> {
				return true;
			}) //
			.verifyComplete();
}

it yields the following JSON: {"links":[{"rel":"self","href":"/"} {"rel":"employees","href":"/employees"}]}

This is basically falling back to no registered codec, and rendering the Spring HATEAOS RepresentationModel object using plain Jackson, i.e. no hypermedia format.

I'm frankly uncertain how to proceed with this. If the server can't produce UBER, it needs to fail somehow. But apparently a default codec is making a Best Effort to push something out.

@gregturn
Copy link
Contributor

gregturn commented Sep 3, 2019

Do we need to register a special handler/filter in WebFlux to cover unregistered media types and then throw an exception?

@wilkinsona
Copy link
Member Author

The media type isn't unregistered. The default WebFlux JacksonJson2Encoder can write application/json and application/*+json. The latter matches application/vnd.amundsen-uber+json so, as far as WebFlux is concerned, it can handle the request.

In some cases, application/*+json is fine. For example Spring Boot's actuator produces application/vnd.spring-boot.actuator.v2+json directly from the object model so no custom codec is required. In other cases, like the one here, application/*+json is too broad as the object model isn't a one-to-one representation of the required JSON. Disabling only the default codec for application/*+json would not suffice here. It would fix the latter example at the cost of breaking the former.

Does the same problem not also occur with MVC? MappingJackson2HttpMessageConverter appears to use the same default media types.

@gregturn
Copy link
Contributor

gregturn commented Sep 4, 2019

Verified that Spring MVC indeed returns a Jackson-based piece of JSON when calling for an unregistered mediatype.

This means I can switch back to default encoders/decoders for WebFlux configuration.

gregturn added a commit that referenced this issue Sep 4, 2019
Spring WebFlux now correctly handles custom codecs. This means we can stop disabling them. This change includes more test cases, verifying Spring MVC configuration for hypermedia as well, verifying both Web MVC and WebFlux are properly and consistently configured.

Probably supercedes: #1047
gregturn added a commit that referenced this issue Sep 5, 2019
With Spring WebFlux properly handling custom codecs, no need to disable the default handlers.

This commit verifies WebFlux configuration in test cases, and also adds an equivalent set of test cases verifying Web MVC configuration as well.

Supercedes: #1047
@gregturn gregturn added this to the 1.0.0.RC2 milestone Sep 5, 2019
@gregturn gregturn self-assigned this Sep 5, 2019
@gregturn gregturn added in: configuration Configuration and setup stack: webflux labels Sep 5, 2019
@gregturn
Copy link
Contributor

gregturn commented Sep 5, 2019

Resolved via fd70fd9.

@gregturn gregturn closed this as completed Sep 5, 2019
gregturn added a commit that referenced this issue Sep 16, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants