codeconsole opened a new issue, #16698:
URL: https://github.com/apache/grails-core/issues/16698
## Background
After #16237, two policies negotiate a response:
- **Grails' negotiation** picks the *format* that selects a renderer, a view
or a `withFormat` block: `response.format`, `request.format` (from
`Content-Type`), `withFormat` and the format `respond` writes in. It chooses
among the types `grails.mime.types` configures, with rules of its own:
- the `Accept` header ignored for the user agents
`grails.mime.disable.accept.header.userAgents` lists, and for XHR requests
unless `grails.mime.disable.accept.header.userAgentsXhr` is set,
- `text/xml` and `application/xml` merged into `xml`, and `+xml` types
preferred to it at equal quality,
- the problem types of RFC 9457 read as the `json` and `xml` formats,
- `params.format` and URL extensions, and the fallback to the first
configured type.
- **Spring MVC's `ContentNegotiationManager`** picks the *media type* among
those its message converters can write. Since #16237 it decides how Spring MVC
writes problems, the values of actions it writes (a returned `ResponseEntity`,
`ProblemDetail` and so on, and, with `grails.controllers.responseBody`, the
values of `@ResponseBody` actions), and the JSON `respond` writes through
Spring MVC.
The parsing is already shared: `DefaultAcceptHeaderParser` reads each media
type with Spring's `MediaType.parseMediaType`, and the Grails data formats are
registered with Spring as format aliases. What remains is the two policies,
which can answer the same request differently. A browser's `*/*` is one
example; a client of a Grails view and of a Spring-written value of the same
action is another.
## Proposal
**Grails 10, opt-in.** Add a setting that resolves `request.format`,
`response.format`, `withFormat` and `respond`'s format through Spring MVC's
`ContentNegotiationManager`, mapping the media type it selects back to the
Grails format `grails.mime.types` gives it. For each Grails rule above, decide
whether to:
- keep it, as a strategy of Spring's manager that applies to Grails actions
only,
- port it to Spring's configuration, such as
`spring.mvc.contentnegotiation.*`, or
- drop it, with an entry in the upgrade guide.
**A comparison spec.** Run a matrix of requests through both policies and
record every answer that differs. The matrix covers `Accept` headers with
qualities, wildcards and `+json`/`+xml` types, browser and XHR user agents,
`?format=` and URL extensions, `Content-Type` for `request.format`, and several
`grails.mime.types` configurations. That record is the evidence for the
default, and the list the upgrade guide gives.
**Grails 11, the default.** Decide whether the setting becomes the default
when the legacy `respond` rendering is removed. By then every JSON and XML body
goes through Spring MVC, and Grails' negotiation only picks views and
`withFormat` blocks.
## Constraints
- `GrailsContentNegotiationStrategy` stays out of the context as a Spring
`ContentNegotiationStrategy` bean, which Spring Security adopts.
- The negotiation of Spring MVC endpoints (`@RestController`, `produces`,
`spring.mvc.contentnegotiation.*`) is unchanged.
- The Grails 9 behaviour stays the default until the setting's default
changes, as for the other migration settings in `grails.config.Settings`.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]