GithubHelp home page GithubHelp logo

timothyfisherdev / http Goto Github PK

View Code? Open in Web Editor NEW
1.0 0.0 0.0 18 KB

A very simple PSR-15/PSR-7 compliant model of the HTTP request-response lifecycle.

License: MIT License

PHP 100.00%
http request-handler request-response psr15 psr7 middleware-dispatchers

http's Introduction

PSR-15/PSR-7 HTTP Library

Build Status Coverage Status

This is a very simple PHP library that models the request/response lifecycle using PSR-7 message objects, and PSR-15 middleware interfaces.

This was mainly created for learning and educational purposes, and for getting more comfortable with PHPUnit, Travis, and Coveralls.

Overview

The purpose of this library is to create a broad outline of the request/response pattern in modern web development. The request/response are modeled through PSR-7 objects: Psr\Http\Message\ServerRequestInterface and Psr\Http\Message\ResponseInterface.

PSR-15 provides two new interfaces that utilize these objects:

  • Psr\Http\Server\RequestHandlerInterface
  • Psr\Http\Server\MiddlewareInterface

The RequestHandlerInterface is used to define an object that will handle a PSR-7 request. Typically, this is done through some sort of "kernel" object that accepts an initial request, and sends the request through a "queue" or stack of MiddlewareInterface objects.

There are two common approaches to how middleware can interpret the request and produce a response: Single Pass and Double Pass.

According to the PSR-15 Meta Document, the Single Pass approach was chosen due to problems with the unreliability of the Double Pass approach. Since middleware objects in the stack are independent and not conscious of each other, passing an empty response object in addition to the request object through the queue causes the response to be ambiguous since the currently acting middleware doesn't know the current state of the response object.

In this form, middleware has no access to a response until one is generated by the request handler. Middleware can then modify the response before returning it (PSR-15 Meta).

Instead, with the Single Pass approach, only the request object is passed to each middleware. The middleware can then decide whether to create a response or pass the request to the next middleware. If the middleware decides to create a response, it can delegate its creation to a factory, but that is outside the scope of this library, and is currently in the works as a separate PSR: PSR-17.

If the middleware decides to relay the request to the next middleware, it sends it back to the kernel which advances its internal pointer in the queue to grab the next middleware to invoke. If all of the middleware in the queue have been invoked, the request handler should have a way to fallback to a default handler in case no middlewares can create a response.

As stated in the PSR-15 Meta Docs:

It is RECOMMENDED that any middleware or request handler that generates a response will either compose a prototype of a PSR-7 ResponseInterface or a factory capable of generating a ResponseInterface instance in order to prevent dependence on a specific HTTP message implementation.

As such, the Http\HttpKernel object accepts a "fallback handler" which is an instance of Psr\Http\Server\RequestHandlerInterface to call when all middleware objects have been exhausted. Each middleware interface is also passed an Http\HandlerProxy proxy object that exposes access to the HttpKernel::handle() method. If a middleware determines that it cannot delegate to its factory to create a response, the kernel handle method is called again, which directs the request to the next middleware, or executes the fallback handler. This is described in just a few lines in the Http\HttpKernel class:

public function handle(ServerRequestInterface $request) : ResponseInterface
{
    // if we have processed all middleware, invoke fallback handler
    if ($this->queue->processed()) {
        return $this->fallbackHandler->handle($request);
    }

    // if not, invoke the next middleware
    return $this->queue->process($request, $this->proxy);
}

This is also described in detail here.

http's People

Contributors

tfisher9180 avatar timothyfisherdev avatar

Stargazers

 avatar

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.