spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
74.56k stars 40.55k forks source link

Provide auto-configuration for Spring HATEOAS's new WebFlux integration #16020

Open wilkinsona opened 5 years ago

wilkinsona commented 5 years ago

A non-exhaustive list of things to consider:

mikrethor commented 5 years ago

Sorry if it's not the right place but before opening an issue. I want ti be sure. Is hateoas compatible with router function or only with controllers?

philwebb commented 5 years ago

@mikrethor I think it might depend on which parts of Spring HATEOAS you are trying to use. The best place to ask is probably stackoverflow. Or you could raise a documentation issue at https://github.com/spring-projects/spring-hateoas/issues if you think things need to be clarified.

gregturn commented 5 years ago

@wilkinsona when I do this, I have managed to get things working with WebFlux...

<properties>
    <java.version>1.8</java.version>
    <spring-hateoas.version>1.0.0.BUILD-SNAPSHOT</spring-hateoas.version>
</properties>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-hateoas</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </exclusion>
    </exclusions>
</dependency>
@SpringBootApplication
@EnableHypermediaSupport(type = { HAL, HAL_FORMS })
public class HackingSpringBootApplication {

    public static void main(String[] args) {
        SpringApplication.run(HackingSpringBootApplication.class, args);
    }
}

Presumably, because this takes Spring MVC off the classpath and puts WebFlux on the classpath, Spring HATEOAS itself is able to pick the right set of beans to register itself properly.

wilkinsona commented 5 years ago

This is still blocked:

wilkinsona commented 5 years ago

In addition to the blocking issues above, a secondary issue is that I don't think we can support the existing spring.hateoas.use-hal-as-default-json-media-type with WebFlux as we can't manipulate the JSON codecs in the same way as we currently manipulate the HTTP message converter with MVC.

If I can get Spring HATEOAS working well enough with WebFlux to confirm the above, I'll open an issue to see if Spring HATEOAS can make it configurable so that the codecs can be configured up front with the desired mime types rather than us having to change them after the fact.

wilkinsona commented 4 years ago

TL;DR: I think we should move this out of 2.2.x or perhaps even close this.

In addition to the ongoing discussions involving @odrotbohm and @bclozel related to media type aliasing which are not going to be resolved in the Framework 5.2/Boot 2.2 timeframe, I am now of the opinion that WebFlux-based auto-configuration will be more of a hinderance than a help to users.

Setting aside the HttpMessageConverter customization that Boot optionally performs and which is servlet-specific, the auto-configuration is reduced to a single annotation:

@EnableHypermediaSupport(type = HypermediaType.HAL)

The expanded range of media types that are supported by Spring HATEOAS mean that Boot auto-configuring HAL and only HAL is harder to justify. As soon as the user specifies @EnableHypermediaSupport (which they are now more likely to want to do), all of the auto-configuration other than the HttpMessageConverter customization backs off. WebFlux-based auto-configuration will have no equivalent HttpMessageConverter auto-configuration so in many cases it would back off entirely as the user specifies @EnableHypermediaSupport with their chosen media types.

Adding WebFlux support would also mean that the starter makes little sense any more. It currently contains three dependencies:

  1. org.springframework.boot:spring-boot-starter-web
  2. org.springframework.hateoas:spring-hateoas
  3. org.springframework.plugin:spring-plugin-core

To allow the starter to apply to be web stacks, 1 would be removed. Furthermore 3 is no longer needed as spring-plugin-core is now a required dependency of spring-hateoas. This would leave the starter with a single module, 2, with the expectation that it's used in combination with spring-boot-starter-web or spring-boot-starter-webflux. A single module starter doesn't serve any purpose so it would make sense to remove it.

As I wrote the above, I realised that much of the same logic could be applied to MVC too. Once the media type aliasing discussion has been resolved (hopefully in the Framework 5.3 timeframe), it may make sense to deprecate Boot's auto-configuration for Spring HATEOAS on the servlet-based web stack. The discussion will hopefully result in a better alternative to Boot's HttpMessageConverter customization which will leave it in the same situation as WebFlux-based auto-configuration where it's just auto-configuring a single annotation that will back of entirely as soon as the user tunes things. There may even be a case for deprecating the auto-configuration in 2.2. There'd be no replacement for spring.hateoas.use-hal-as-default-json-media-type but with hindsight adding that property may have been a mistake anyway. Deprecation now would help to reduce confusion about what starter to use when using HATEOAS with WebFlux with the answer being that Spring HATEOAS should be used directly without any need for a starter as it's a single dependency.

What do you think, @odrotbohm and @gregturn? My reasoning above is based on there actually being very little for Boot to auto-configure these days. If there are, in fact, some more new features for which auto-configuration would make sense then my reasoning will no longer apply.

odrotbohm commented 4 years ago

Totally with you, Andy. The shim on top of @EnableHypermediaSupport has always been on the thin side, compared to other auto-configuration and the changes and additions made for Spring HATEOAS 1.0 create more emphasis on the users very explicitly choosing what's supposed to be going on as it's effectively part of the overall API design.

Also, we have tweaked Spring HATEOAS configuration model in a way that it's now using a (Spring Boot) provided ObjectMapper as is, so that quite a bit of the integration that went the other way (Boot making HATEOAS work in its world) should be mostly obsolete now.

Let's see what feedback we get for HATEOAS 1.0 and Boot 2.2 and incorporate that into a sort of clean slate start for 1.1/2.3 with a plausible option of doing exactly nothing.

wilkinsona commented 4 years ago

Sold. Thanks for the quick response, @odrotbohm.

gregturn commented 4 years ago

Per our video chat, the following points were agreed upon:

In the meantime, server-side configuration of both Spring MVC and Spring WebFlux will remain squarely maintained inside Spring HATEOAS. And providing APIs for users to easily configure RestTemplate, WebClient, TestRestTemplate, and WebTestClient beans shall also be developer directly by Spring HATEAOAS. Once in place, Boot will be free to pick them up when our story is more crisp.

rfelgent commented 3 years ago

Hi,

any update on that issue ? So far, I haven't seen anything in the 2.4.× release notes.

wilkinsona commented 3 years ago

Nothing to report at this time, @rfelgent. The issue remains open so it is to be expected that there's nothing in the 2.4.x release notes.