Skip to content
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

@route content negotiation #1173

Open
sharpaper opened this issue Oct 21, 2019 · 2 comments
Open

@route content negotiation #1173

sharpaper opened this issue Oct 21, 2019 · 2 comments
Labels
Feature This is a feature request, not a bug. Open for discussion.

Comments

@sharpaper
Copy link

sharpaper commented Oct 21, 2019

Does Bottle support content negotiation? Sometimes it's the client that specifies to the server what format it wants back, for example the same URL can be used to return an HTML version of the resource, or JSON, or RDF, or XML. Can Bottle support this? More or less like this:

@route('/resource', accept-header='text/html'):
def html():
    return resource as html

@route('/resource', accept-header='text/turtle'):
def turtle():
    return resource as turtle file

@route('/resource', accept-header='application/xml'):
def xml():
    return resource as xml file
@defnull
Copy link
Member

defnull commented Oct 21, 2019

No. Content negotiation is quite complex (if you actually want to implement the spec) and also a completely optional part of HTTP. Perhaps caused by the complexity and unintuitive rules, it is not used very widely. Most REST APIs or traditional webpages only offer a single representation per route and completely ignore the Accept header. Some even side-step the spec and allow users to add common file name extensions to request routes to choose an output format.

If you really need that, I'd suggest implementing it as a plugin or simple helper function hat calls different serializers and/or handler functions based on the best match. For example:

@route('/resource'):
def handle():
    data = ...

    return choose({
        'text/html; q=0.1': lambda: to_html(data),
        'text/turtle': lambda: to_turtle(data),
        'application/xml': lambda: to_xml(data),
    }, request.headers.get("Accept","*/*"))

@defnull defnull added the Feature This is a feature request, not a bug. Open for discussion. label Oct 21, 2019
@sharpaper
Copy link
Author

I've just noticed that pyramid has something like this. See here, scroll down to "Predicate Arguments > header". Basically, before a request is dispatched to a controller it's possible to check if a header exist in addition to the method and pattern of the request. Would this be possible to do for Bottle as well? It wouldn't seem too difficult to check for a header, but I don't know...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature This is a feature request, not a bug. Open for discussion.
Projects
None yet
Development

No branches or pull requests

2 participants