Coder Social home page Coder Social logo

negotiation-middleware's Introduction

NegotiationMiddleware

NegotiationMiddleware provides content negotiation middleware for PHP applications using a middleware signature that requires a request object, a response object, and the next callable in the middleware stack.

This library depends on willdurand/negotation for content negotiation. It allows you to add negotiation to a middleware stack that:

  1. Identifies and matches against a list of acceptable media types.
  2. Supplies a default media type in the absence of an Accept request header.
  3. Enriches the request object with the negotiated media type.

If the negotiator cannot determine which media type to use in response to the request, it will return a response with a 406 Not Acceptable status.

Installation

Use Composer to install NegotiationMiddleware:

$ composer require rszrama/negotiation-middleware

This will install the library and its dependencies. NegotiationMiddleware requires PHP 5.4.0 or newer.

Usage

Add an instance of NegotiationMiddleware\Negotiator to an application or route level middleware stack, passing two arguments to the constructor: an array of acceptable media types to be matched against and a boolean indicating whether or not the middleware should simply match the first acceptable media type in the absence of an Accept header in the request.

Example from Slim 3.x:

<?php

require 'vendor/autoload.php';

use \NegotiationMiddleware\Negotiator;

$app = new \Slim\App();

$app
    ->get('/hello', function(Slim\Http\Request $request, Slim\Http\Response $response, $args) {
        return $response->write('Hello, world!');
    })
    ->add(new Negotiator(['text/html', 'application/json'], TRUE));

$app->run();

In this case, a request to /hello from a web browser will more than likely match the text/html media type specified as an acceptable media type for this route (which is just as well, given our response isn't valid JSON). However, if the server received a request that did not have an Accept header, it will still match to text/html since we instructed the object to supply a default media type.

Note that the Slim\Http\Request object implements PSR-7's ServerRequestInterface. Negotiator::__invoke() requires an instance of this interface to store the negotiated media type in the request object using an attribute named mediaType.

Thus, the route closure could print the negotiated media type like so:

$app
    ->get('/hello', function(Slim\Http\Request $request, Slim\Http\Response $response, $args) {
        $mediaType = $request->getAttribute('mediaType')->getValue();
        return $response->write($mediaType);
    })
    ->add(new Negotiator(['text/html', 'application/json'], TRUE));

The mediaType attribute is an instance of \Negotiation\Accept, which contains a variety of methods for inspecting the actual matched media type from the request header. Refer to the class documentation of [willdurand/negotiation] (https://github.com/willdurand/Negotiation) for more information.

Middleware Signature

NegotiationMiddleware uses the middleware signature required by Slim 3.x, that of a callable that accepts three arguments: a PSR-7 request object, a PSR-7 response object, and a callable that represents the next middleware in the stack.

This pattern and its usefulness thanks to the adoption of PSR-7 are discussed in a helpful [blog post by Matthew O'Phinney] (https://mwop.net/blog/2015-01-08-on-http-middleware-and-psr-7.html), including a similar example:

<?php

use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;

class Middleware {
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next) {
        // Execute code before calling the next middleware.
        $next($request, $response);
        // Execute code after calling the next middleware.
        return $response;
    }
}

Since this implementation is not specific to Slim (or any other framework), it can be reused by any application that uses the same middleware signature or adapted to work with other middleware patterns that still make use of PSR-7 request and response objects.

License

NegotiationMiddleware is licensed under the MIT license. See LICENSE for more information.

negotiation-middleware's People

Contributors

mhor avatar rszrama avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

mhor gofabian

negotiation-middleware's Issues

Negotiation constraint (composer)

Hi Ryan! Nice work here ;-)

One remark though: it would be better not to use dev-master in your composer.json files. It is "bad" as things can break for some reasons, and without you noticing anything. Generally speaking, relying on proper version numbers (such as tags) is better, even for unstable releases of a package. For Negotiation, you should require willdurand/negotiation:v2.0.0-alpha1.

William

Cannot commit this package when installed via composer

Good day,

My composer file looks like the following:

{
    "minimum-stability": "dev",
    "prefer-stable": true,
    "require": {
        "psr/http-message": "1.0",
        "slim/slim": "^3.8.1",
        "respect/validation": "^1.1",
        "rszrama/negotiation-middleware": "dev-master"
    }
}

When I do composer update and install, the files install on my machine. That is not the problem. But with every other package in my vendor directory, I can commit the full source code to my own project, without the need for submodule unpacking. Instead, git is reporting that these files are "under version control" and won't commit them.

Am I supposed to be retrieving this package via a submodule? I see no options for installing via a submodule in this package's readme - only via composer.

I would prefer to install this package via composer and commit the full code to my project like I do with every other. Please assist with this. Thank you.

Please release this as stable

Good day,

My composer file looks like the following:

{
    "minimum-stability": "dev",
    "prefer-stable": true,
    "require": {
        "psr/http-message": "1.0",
        "slim/slim": "^3.8.1",
        "respect/validation": "^1.1",
        "rszrama/negotiation-middleware": "dev-master"
    }
}

Ideally, my file should look like:

{
    "require": {
        "slim/slim": "^3.8.1",
        "respect/validation": "^1.1",
        "rszrama/negotiation-middleware": "^1.0"
    }
}

However, I need extra lines for several reasons. The two stability lines could be removed if this package were tested against a stable version of willdurand/negotiation (2.3.1 is the latest stable version as of right now) and then publishing this package as stable 1.0.

I need the http-message line, since this package depends upon

"psr/http-message": "1.0",

My understanding is that adding a caret would be safe, and would allow my project to install the current version 1.0.1 instead:

"psr/http-message": "^1.0",

Thank you.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.