NAME
    Plack::Middleware::Negotiate - Apply HTTP content negotiation as Plack
    middleware

SYNOPSIS
        builder {
            enable 'Negotiate',
                formats => {
                    xml  => { 
                        type    => 'application/xml',
                        charset => 'utf-8',
                    },
                    html => { type => 'text/html', language => 'en' },
                    _    => { size => 0 }  # default values for all formats           
                },
                parameter => 'format', # e.g. http://example.org/foo?format=xml
                extension => 'strip';  # e.g. http://example.org/foo.xml
            $app;
        };

DESCRIPTION
    Plack::Middleware::Negotiate applies HTTP content negotiation to a PSGI
    request. In addition to normal content negotiation from a list of
    defined "formats" one may enable explicit format selection with a path
    "extension" or query "parameter". In summary, the following methods are
    tried in this order to negotiate a known format:

    HTTP GET/POST format parameter (if enabled with option "parameter")
        e.g. format is set to xml for http://example.org/foo?format=xml if
        format xml has been defined.

    URL path extension (if enabled with option "extension")
        e.g. format is set to xml for http://example.org/foo.xml if format
        xml has been defined.

    HTTP Accept Header (unless disabled with option "explicit")
        e.g. format is set to xml if format xml has been defined with
        content type application/xml for Accept header value
        "application/xml".

    The PSGI environment key "negotiate.format" is set to the chosen format
    name after negotiation. The PSGI response is enriched with corresponding
    HTTP headers Content-Type and Content-Language unless these headers
    already exist.

    If used as pure application, this middleware returns a HTTP status code
    406 if no format could be negotiated.

METHODS
  new( formats => { ... } [, %options ] )
    Creates a new negotiation middleware with a given set of formats.

  negotiate( $env )
    Chooses a format based on a PSGI request. The request is first checked
    for explicit format selection via "parameter" and "extension" (if
    configured) and then passed to HTTP::Negotiate. On success the method
    returns a format name. The method may modify the PSGI request
    environment keys PATH_INFO and SCRIPT_NAME if format was selected by
    extension set to "strip", and strips the "format" HTTP GET query
    parameter from QUERY_STRING if "parameter" is set to a format. If format
    was selected by HTTP POST body parameter, the parameter it is not
    stripped from the request.

  known( $format )
    Tells whether a format name is known. By default this is the case if the
    format name exists in the list of formats.

  about( $format )
    If the format was specified, this method returns a hash with "quality",
    "type", "encoding", "charset", and "language". Missing values are set to
    the default.

  variants
    Returns a list of content variants to be used in HTTP::Negotiate. The
    return value is an array reference of array references, each with seven
    elements: format name, source quality, type, encoding, charset,
    language, and size. The size is always zero.

  add_headers( \@headers, $format )
    Add apropriate HTTP response headers for a format unless the headers are
    already given.

CONFIGURATION
    formats
        A list of formats to choose among. Each format can be defined with
        "type", "quality" (defaults to 1), "encoding", "charset", and
        "language". The special format name "_" (underscore) is reserved to
        define default values for all formats.

        Formats can also be used to directly route the request to a PSGI
        application:

            my $app = Plack::Middleware::Negotiate->new(
                formats => {
                    json => { 
                        type => 'application/json',
                        app  => $json_app,
                    },
                    html => {
                        type => 'text/html',
                        app  => $html_app,
                    }
                }
            );

    parameter
        Enables explicit format selection with a query paramater, for
        instance "format". Both HTTP GET and HTTP POST body parameters are
        supported.

    extension
        Enables explicit format selection with a virtual file extension. The
        value "strip" strips a known format name from the request path. The
        value "keep" keeps the format name extension after format selection.

        The middleware takes care for rewriting and restoring PATH_INFO if
        it is configured to detect and strip a format extension.

    explicit
        Disables content negotiation based on HTTP headers.

LOGGING AND DEBUGGING
    Plack::Middleware::Negotiate uses "Log::Contextual" to emit a logging
    message during content negotiation on logging level "trace". Just set:

        $ENV{PLACK_MIDDLEWARE_NEGOTIATE_TRACE} = 1;

LIMITATIONS
    The Content-Encoding HTTP response header is not automatically set on a
    response and content negotiation based on size is not supported. Feel
    free to comment on whether and how this middleware should support both.

CONTRIBUTORS
    Jakob Voß, Christopher A. Kirke

COPYRIGHT AND LICENSE
    Copyright 2014- Jakob Voß

    This library is free software; you can redistribute it and/or modify it
    under the same terms as Perl itself.

SEE ALSO
    Content negotiation in this module is based on HTTP::Negotiate. See
    HTTP::Headers::ActionPack::ContentNegotiation for an alternative
    approach. This module has some overlap with
    Plack::Middleware::SetAccept.

