2017 © Pedro Peláez
 

library zf-content-negotiation

ZF Module providing content-negotiation features

image

zfcampus/zf-content-negotiation

ZF Module providing content-negotiation features

  • Monday, May 7, 2018
  • by zendframework
  • Repository
  • 14 Watchers
  • 18 Stars
  • 916,129 Installations
  • PHP
  • 38 Dependents
  • 0 Suggesters
  • 38 Forks
  • 12 Open issues
  • 35 Versions
  • 6 % Grown

The README.md

ZF Content Negotiation

Repository abandoned 2019-12-31

This repository has moved to laminas-api-tools/api-tools-content-negotiation., (*1)

Build Status Coverage Status, (*2)

Introduction

zf-content-negotiation is a module for automating content negotiation tasks within a Zend Framework application., (*3)

The following features are provided, (*4)

  • Mapping Accept header media types to specific view model types, and automatically casting controller results to those view model types.
  • Defining Accept header media type whitelists; requests with Accept media types that fall outside the whitelist will be immediately rejected with a 406 Not Acceptable response.
  • Defining Content-Type header media type whitelists; requests sending content bodies with Content-Type media types that fall outside the whitelist will be immediately rejected with a 415 Unsupported Media Type response.

Requirements

Please see the composer.json file., (*5)

Installation

Run the following composer command:, (*6)

$ composer require zfcampus/zf-content-negotiation

Alternately, manually add the following to your composer.json, in the require section:, (*7)

"require": {
    "zfcampus/zf-content-negotiation": "^1.2"
}

And then run composer update to ensure the module is installed., (*8)

Finally, add the module name to your project's config/application.config.php under the modules key:, (*9)

return [
    /* ... */
    'modules' => [
        /* ... */
        'ZF\ContentNegotiation',
    ],
    /* ... */
];

zf-component-installer

If you use zf-component-installer, that plugin will install zf-content-negotiation as a module for you., (*10)

Configuration

User Configuration

The top-level configuration key for user configuration of this module is zf-content-negotiation., (*11)

Key: controllers

The controllers key is utilized for mapping a content negotiation strategy to a particular controller service name (from the top-level controllers section). The value portion of the controller array can either be a _named selector_ (see selectors below), or a selector definition., (*12)

A selector definition consists of an array with the key of the array being the name of a view model, and the value of it being an indexed array of media types that, when matched, will select that view model., (*13)

Example:, (*14)

'controllers' => [
    // Named selector:
    'Application\Controller\HelloWorld1' => 'Json',

    // Selector definition:
    'Application\Controller\HelloWorld2' => [
        'ZF\ContentNegotiation\JsonModel' => [
            'application/json',
            'application/*+json',
        ],
    ],
],

Key: selectors

The selectors key is utilized to create named selector definitions for reuse between many different controllers. The key part of the selectors array will be a name used to correlate the selector definition (which uses the format described in the controllers key)., (*15)

Example:, (*16)

'selectors' => [
    'Json' => [
        'ZF\ContentNegotiation\JsonModel' => [
            'application/json',
            'application/*+json',
        ],
    ],
],

A selector can contain multiple view models, each associated with different media types, allowing you to provide multiple representations. As an example, the following selector would allow a given controller to return either JSON or HTML output:, (*17)

'selectors' => [
    'HTML-Json' => [
        'ZF\ContentNegotiation\JsonModel' => [
            'application/json',
            'application/*+json',
        ],
        'ZF\ContentNegotiation\ViewModel' => [
            'text/html',            
        ],
    ],
],

Key: accept_whitelist

The accept_whitelist key is utilized to instruct the content negotiation module which media types are acceptable for a given controller service name. When a controller service name is configured in this key, along with an indexed array of matching media types, only media types that match the Accept header of a given request will be allowed to be dispatched. Unmatched media types will receive a 406 Cannot honor Accept type specified response., (*18)

The value of each controller service name key can either be a string or an array of strings., (*19)

Example:, (*20)

'accept_whitelist' => [
    'Application\\Controller\\HelloApiController' => [
        'application/vnd.application-hello+json',
        'application/hal+json',
        'application/json',
    ],
],

Key: content_type_whitelist

The content_type_whitelist key is utilized to instruct the content negotiation module which media types are valid for the Content-Type of a request. When a controller service name is configured in this key, along with an indexed array of matching media types, only media types that match the Content-Type header of a given request will be allowed to be dispatched. Unmatched media types will receive a 415 Invalid content-type specified response., (*21)

The value of each controller service name key can either be a string or an array of strings., (*22)

Example:, (*23)

'content_type_whitelist' => [
    'Application\\Controller\\HelloWorldController' => [
        'application/vnd.application-hello-world+json',
        'application/json',
    ],
],

Key: x_http_method_override_enabled

  • Since 1.3.0

This boolean flag determines whether or not the HttpMethodOverrideListener will be enabled by default., (*24)

Key: http_override_methods

  • Since 1.3.0

The http_override_methods key is utilized to provide the HttpMethodOverrideListener with a map of allowed override methods for a given HTTP method, as specified via the X-HTTP-Method-Override header. Essentially, the values are:, (*25)

'Incoming HTTP request method' => $arrayOfAllowedOverrideMethods,

As an example, if you want to allow the X-HTTP-Method-Override header to allow overriding HTTP GET requests with an alternate method, you might define this as follows:, (*26)

'x_http_method_override_enabled' => true,
'http_override_methods' => [
    'GET' => [
        'HEAD',
        'POST',
        'PUT',
        'DELETE',
        'PATCH',
    ],
];

Then, to make a request, you could do the following:, (*27)

GET /foo HTTP/1.1
Host: example.com
X-HTTP-Method-Override: PATCH

some=content&more=content

The above would then be interpreted as a PATCH request. If the same request were made via HTTP POST, or if a GET request were made with an override value of OPTIONS, the listener would raise a problem, as, in the former case, no maps are defined for POST, and, in the latter, OPTIONS is not in the map for GET., (*28)

System Configuration

The following configuration is provided in config/module.config.php to enable the module to function:, (*29)

'filters' => [
    'aliases'   => [
        'Zend\Filter\File\RenameUpload' => 'filerenameupload',
    ],
    'factories' => [
        'filerenameupload' => Factory\RenameUploadFilterFactory::class,
    ],
],

'validators' => [
    'aliases'   => [
        'Zend\Validator\File\UploadFile' => 'fileuploadfile',
    ],
    'factories' => [
        'fileuploadfile' => Factory\UploadFileValidatorFactory::class,
    ],
],

'service_manager' => [
    'factories' => [
        ContentTypeListener::class        => InvokableFactory::class,
        'Request'                         => Factory\RequestFactory::class,
        AcceptListener::class             => Factory\AcceptListenerFactory::class,
        AcceptFilterListener::class       => Factory\AcceptFilterListenerFactory::class,
        ContentTypeFilterListener::class  => Factory\ContentTypeFilterListenerFactory::class,
        ContentNegotiationOptions::class  => Factory\ContentNegotiationOptionsFactory::class,
        HttpMethodOverrideListener::class => Factory\HttpMethodOverrideListenerFactory::class,
    ],
],

'controller_plugins' => [
    'aliases' => [
        'routeParam'  => ControllerPlugin\RouteParam::class,
        'queryParam'  => ControllerPlugin\QueryParam::class,
        'bodyParam'   => ControllerPlugin\BodyParam::class,
        'routeParams' => ControllerPlugin\RouteParams::class,
        'queryParams' => ControllerPlugin\QueryParams::class,
        'bodyParams'  => ControllerPlugin\BodyParams::class,
    ],
    'factories' => [
        ControllerPlugin\RouteParam::class  => InvokableFactory::class,
        ControllerPlugin\QueryParam::class  => InvokableFactory::class,
        ControllerPlugin\BodyParam::class   => InvokableFactory::class,
        ControllerPlugin\RouteParams::class => InvokableFactory::class,
        ControllerPlugin\QueryParams::class => InvokableFactory::class,
        ControllerPlugin\BodyParams::class  => InvokableFactory::class,
    ],
],

ZF Events

Listeners

ZF\ContentNegotiation\AcceptListener

This listener is attached to the MvcEvent::EVENT_DISPATCH event with priority -10. It is responsible for performing the actual selection and casting of a controller's view model based on the content negotiation configuration., (*30)

ZF\ContentNegotiation\ContentTypeListener

This listener is attached to the MvcEvent::EVENT_ROUTE event with a priority of -625. It is responsible for examining the Content-Type header in order to determine how the content body should be deserialized. Values are then persisted inside of a ParameterDataContainer which is stored in the ZFContentNegotiationParameterData key of the MvcEvent object., (*31)

ZF\ContentNegotiation\AcceptFilterListener

This listener is attached to the MvcEvent::EVENT_ROUTE event with a priority of -625. It is responsible for ensuring the controller selected by routing is configured to respond to the specific media type in the current request's Accept header. If it cannot, it will short-circuit the MVC dispatch process by returning a 406 Cannot honor Accept type specified response., (*32)

ZF\ContentNegotiation\ContentTypeFilterListener

This listener is attached to the MvcEvent::EVENT_ROUTE event with a priority of -625. It is responsible for ensuring the route matched controller can accept content in the request body specified by the media type in the current request's Content-Type header. If it cannot, it will short-circuit the MVC dispatch process by returning a 415 Invalid content-type specified response., (*33)

ZF\ContentNegotiation\HttpMethodOverrideListener

  • Since 1.3.0

This listener is attached to the MvcEvent::EVENT_ROUTE event with a priority of -40, but only if the x_http_method_override_enabled configuration flag was toggle on. It is responsible for checking if an X-HTTP-Method-Override header is present, and, if so, if it contains a value in the set allowed for the current HTTP request method invoked. If so, it resets the HTTP request method to the header value., (*34)

ZF Services

Controller Plugins

ZF\ContentNegotiation\ControllerPlugin\RouteParam (a.k.a "routeParam")

A controller plugin (Zend\Mvc\Controller\AbstractActionController callable) that will return a single parameter with a particular name from the route match., (*35)

use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        return $this->routeParam('id', 'someDefaultValue');
    }
}

ZF\ContentNegotiation\ControllerPlugin\QueryParam (a.k.a "queryParam")

A controller plugin (Zend\Mvc\Controller\AbstractActionController callable) that will return a single parameter from the current request query string., (*36)

use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        return $this->queryParam('foo', 'someDefaultValue');
    }
}

ZF\ContentNegotiation\ControllerPlugin\BodyParam (a.k.a "bodyParam")

A controller plugin (Zend\Mvc\Controller\AbstractActionController callable) that will return a single parameter from the content-negotiated content body., (*37)

use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        return $this->bodyParam('foo', 'someDefaultValue');
    }
}

ZF\ContentNegotiation\ControllerPlugin\RouteParams (a.k.a "routeParams")

A controller plugin (Zend\Mvc\Controller\AbstractActionController callable) that will return a all the route parameters., (*38)

use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        return $this->routeParams()
    }
}

ZF\ContentNegotiation\ControllerPlugin\QueryParams (a.k.a "queryParams")

A controller plugin (Zend\Mvc\Controller\AbstractActionController callable) that will return a all the query parameters., (*39)

use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        return $this->queryParams()
    }
}

ZF\ContentNegotiation\ControllerPlugin\BodyParams (a.k.a "bodyParams")

A controller plugin (Zend\Mvc\Controller\AbstractActionController callable) that will return a all the content-negotiated body parameters., (*40)

use Zend\Mvc\Controller\AbstractActionController;

class IndexController extends AbstractActionController
{
    public function indexAction()
    {
        return $this->bodyParams()
    }
}

The Versions

11/04 2014

1.0.0beta2

1.0.0.0-beta2 http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

11/04 2014

1.0.0-beta3

1.0.0.0-beta3 http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

09/04 2014

dev-feature/readme-documentation

dev-feature/readme-documentation http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

18/03 2014

1.0.0beta1

1.0.0.0-beta1 http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

28/02 2014

0.9.0

0.9.0.0 http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

28/02 2014

0.9.1

0.9.1.0 http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

17/12 2013

0.8.0

0.8.0.0 http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

15/11 2013

0.7.0

0.7.0.0 http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

03/10 2013

0.6.0

0.6.0.0 http://apigility.org/

ZF2 Module providing content-negotiation features

  Sources   Download

BSD-3-Clause

The Requires

 

The Development Requires

zf2 zend module content-negotiation

02/10 2013

dev-feature/readme-license

dev-feature/readme-license

  Sources   Download

The Requires

 

The Development Requires

06/08 2013

dev-feature/accept-filter

dev-feature/accept-filter

  Sources   Download

The Requires

 

The Development Requires

05/08 2013

dev-hotfix/acceptable-view-model-plugin

dev-hotfix/acceptable-view-model-plugin

  Sources   Download