Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Quality-of-source factor #77

Closed
SteveTalbot opened this issue Feb 1, 2016 · 3 comments
Closed

Quality-of-source factor #77

SteveTalbot opened this issue Feb 1, 2016 · 3 comments
Milestone

Comments

@SteveTalbot
Copy link

Hi,

I'd like to propose a simple way to specify relative priorities of media types, languages, encodings or character sets on the server side, without introducing a backward-compatibility break.

Current behaviour

The programmer specifies a list of available media types, in order of preference, when calling the getBest() function.

The client can specify quality scores against each acceptable type in the Accept header. The default score if not specified is 1.0.

The negotiator finds matches as per RFC 7231, and sets the quality of a match equal to the quality score from the Accept header.

If there is more than one match, the best match is the one with the highest quality score.

In the event of multiple matches with the same quality score, the negotiator returns the match that occurred earliest in the programmer's list.

Proposed behaviour

I'd like to be able to specify a quality of source factor, like in Apache's content negotiation. For example:

$priorities = array('text/html; charset=UTF-8; q=1.0', 'application/pdf; q=0.9');

The negotiator would still find matches as per RFC 7231, but would set the quality of the match equal to the quality score from the Accept header multiplied by the quality-of-source factor specified by the programmer.

The best match is the one with the highest quality.

In the event of multiple matches with the same quality, the negotiator returns the match that occurred earliest in the programmer's list. So if the programmer has not specified any quality-of-source factors, the behaviour would be exactly the same as it is now.

Implementation

Because the priorities are already parsed the same way as the headers, it's a one-line change to implement this. Simply change line 64 of AbstractNegotiator from:

return new Match($header->getQuality(), $score, $index);

to:

return new Match($header->getQuality() * $priority->getQuality(), $score, $index);

Making this change doesn't break any of the existing unit tests. I'm happy to submit a pull request.

Thanks,
Steve

@neural-wetware
Copy link
Contributor

It's a simple enough change and would be backwards compatible. Can you give an example of how this is useful? Otherwise, it's just bloat.

@SteveTalbot
Copy link
Author

The Apache documentation uses images as a simple example for content type negotiation. If the image has transparent areas, a format that can represent alpha-channel transparency (e.g. PNG) would be of higher quality than one with simple transparency (e.g. GIF), which in turn would be better than the many formats that can't represent transparency at all. So, even if the client has a stronger preference for GIF than PNG, it might be better to send the PNG.

For language negotiation, imagine we have an official document that was originally written in English, officially translated and approved by the government in French, and unofficially translated to German. The quality of source of the English variant is the highest, followed by the French, then the German. If the client sends a higher quality factor for German than for French, it may still be more appropriate to send the French version, because it is an official version.

We're thinking of using negotiation for a RESTful API. We'll set the quality of source factor to reflect the richness of information that can be sent in each format. The client can send an Accept header indicating which response formats it supports and prefers; the API will respond with the best response format, taking into account the quality of source and the client's preference.

@neural-wetware
Copy link
Contributor

I think this looks good. It's up to @willdurand to merge.

@willdurand willdurand added this to the 2.1.0 milestone Aug 30, 2016
willdurand added a commit that referenced this issue Sep 4, 2016
Add support for quality-of-source factor [#77]
# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants