You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
If only HAL is registered via @EnableHypermediaSupport, and the client requests Collection+JSON via an Accept header, Spring Framework will fall back to it's handler for application/*-json.
Is this proper behavior? If not, what is?
This is a continuation of the discussion from #1064.
Is the idea is to throw an exception when asking for a hypermedia type not registered but to fallback to that catchall handler?
Maybe HATEOAS needs a handler registered after all others that if it gets hit and the requested type is hypermedia mediatype it throw an exception. But if the requested mediatype is NOT one of ours it lets it go.
I'm not sure if it is either. My concern is that, depending on what the answer is, breaking changes may be required to implement it. It feels like the sort of thing that should be resolved before the restrictions of reaching 1.0 come into play.
The javadoc for canEncode says that it returns "whether the encoder supports the given source element type and the MIME type". Returning true and then failing in encode and encodeValue because the encoder does not, in fact, support the MIME type doesn't seem to honour that contract.
I want it to match if the MimeType is one of our hypermedia mime types. But then blow up on encoding.
This is the one after the “real” handlers. Hence, if you register UBER and then request HAL, it is skipped by UBER but picked up by this one, and generates the exception.
Probably need a better name to communicate it’s purpose. And need a decoder equivalent. And probably an MVC equivalent.
I understand the purpose, but it feels like an abuse of the Encoder contract to me. I'm concerned about unwanted side-effects that may occur in a large app. I don't think that you can guarantee that your Encoder will always be last. If another Encoder is added after it that can handle a hypermedia MIME type, the encoder proposed here will prevent it from being called.
Have you talked to anyone on the Framework team about this? I know that @bclozel was interested in the use case, for example.
In general, Spring Framework with the following rules:
a codec should be registered against a MIME type only if can actually handle it (so canEncode should only return true if, besides an unpredictable runtime error happens, it should handle the encoding properly).
content negotiation is handled in a way that the Framework selects the best available media type (if any compatible), or responds with an HTTP client error
I agree that the registered application/*+json media type in Framework can be an issue. This registration is generally useful because developers can use custom media types and add meaning to the representation (versioning for example). Technically, media types with the +json suffix mean that they can be processed as regular JSON. It's a fallback, and clients should fail if this is not something they can process.
In any case, if a client asks for application/something+json to a Spring web application, the application might respond with application/json, even if Spring HATEOAS is not involved at all. I think we should keep this behavior consistent and only reconsider this in Framework if necessary.
Activity
gregturn commentedon Sep 15, 2019
I’m not sure what the proper response here is.
Is the idea is to throw an exception when asking for a hypermedia type not registered but to fallback to that catchall handler?
Maybe HATEOAS needs a handler registered after all others that if it gets hit and the requested type is hypermedia mediatype it throw an exception. But if the requested mediatype is NOT one of ours it lets it go.
Not sure if any of this is blocking for 1.0 GA.
wilkinsona commentedon Sep 16, 2019
I'm not sure if it is either. My concern is that, depending on what the answer is, breaking changes may be required to implement it. It feels like the sort of thing that should be resolved before the restrictions of reaching 1.0 come into play.
gregturn commentedon Sep 18, 2019
When I register this
Encoder
after all others, it properly fails if you ask for an unregistered Spring HATEOAS media type.wilkinsona commentedon Sep 18, 2019
The javadoc for
canEncode
says that it returns "whether the encoder supports the given source element type and the MIME type". Returningtrue
and then failing inencode
andencodeValue
because the encoder does not, in fact, support the MIME type doesn't seem to honour that contract.gregturn commentedon Sep 18, 2019
I want it to match if the MimeType is one of our hypermedia mime types. But then blow up on encoding.
This is the one after the “real” handlers. Hence, if you register UBER and then request HAL, it is skipped by UBER but picked up by this one, and generates the exception.
Probably need a better name to communicate it’s purpose. And need a decoder equivalent. And probably an MVC equivalent.
gregturn commentedon Sep 18, 2019
If you ask for something else like Actuator’s MimeType, that should bypass this extra encoder too.
wilkinsona commentedon Sep 18, 2019
I understand the purpose, but it feels like an abuse of the
Encoder
contract to me. I'm concerned about unwanted side-effects that may occur in a large app. I don't think that you can guarantee that yourEncoder
will always be last. If anotherEncoder
is added after it that can handle a hypermedia MIME type, the encoder proposed here will prevent it from being called.Have you talked to anyone on the Framework team about this? I know that @bclozel was interested in the use case, for example.
gregturn commentedon Sep 18, 2019
No i haven’t chatted with them directly.
If it’s this risky I doubt the ability to add this to 1.0.
bclozel commentedon Sep 18, 2019
In general, Spring Framework with the following rules:
canEncode
should only returntrue
if, besides an unpredictable runtime error happens, it should handle the encoding properly).I agree that the registered
application/*+json
media type in Framework can be an issue. This registration is generally useful because developers can use custom media types and add meaning to the representation (versioning for example). Technically, media types with the+json
suffix mean that they can be processed as regular JSON. It's a fallback, and clients should fail if this is not something they can process.In any case, if a client asks for
application/something+json
to a Spring web application, the application might respond withapplication/json
, even if Spring HATEOAS is not involved at all. I think we should keep this behavior consistent and only reconsider this in Framework if necessary.gregturn commentedon Sep 18, 2019
Based on all comments I’m closing this as works as designed.