Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/decodelabs/harvest
PSR-15 HTTP stack without the mess
https://github.com/decodelabs/harvest
Last synced: 1 day ago
JSON representation
PSR-15 HTTP stack without the mess
- Host: GitHub
- URL: https://github.com/decodelabs/harvest
- Owner: decodelabs
- License: mit
- Created: 2023-10-30T13:21:43.000Z (about 1 year ago)
- Default Branch: develop
- Last Pushed: 2024-09-04T21:17:03.000Z (4 months ago)
- Last Synced: 2024-12-20T21:41:52.837Z (20 days ago)
- Language: PHP
- Size: 98.6 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# Harvest
[![PHP from Packagist](https://img.shields.io/packagist/php-v/decodelabs/harvest?style=flat)](https://packagist.org/packages/decodelabs/harvest)
[![Latest Version](https://img.shields.io/packagist/v/decodelabs/harvest.svg?style=flat)](https://packagist.org/packages/decodelabs/harvest)
[![Total Downloads](https://img.shields.io/packagist/dt/decodelabs/harvest.svg?style=flat)](https://packagist.org/packages/decodelabs/harvest)
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/decodelabs/harvest/integrate.yml?branch=develop)](https://github.com/decodelabs/harvest/actions/workflows/integrate.yml)
[![PHPStan](https://img.shields.io/badge/PHPStan-enabled-44CC11.svg?longCache=true&style=flat)](https://github.com/phpstan/phpstan)
[![License](https://img.shields.io/packagist/l/decodelabs/harvest?style=flat)](https://packagist.org/packages/decodelabs/harvest)### PSR-15 HTTP stack without the mess
Harvest provides a unified PSR-15 HTTP stack with a simple, expressive API on top of PHP Fibers to avoid common pitfalls of other PSR-15 implementations such as call stack size, memory usage and Middleware traversal.
_Get news and updates on the [DecodeLabs blog](https://blog.decodelabs.com)._
---
## Installation
Install via Composer:
```bash
composer require decodelabs/harvest
```## Usage
Harvest provides the full PSR-15 stack, including Request, Response, Middleware and Handler interfaces.
```php
use DecodeLabs\Harvest;
use DecodeLabs\Harvest\Dispatcher;
use DecodeLabs\Harvest\Middleware\ContentSecurityPolicy;// Create a Dispatcher
$dispatcher = new Dispatcher(
$myPsrContainer // Ideally initialize with a PSR-11 container
);// Add middleware
$dispatcher->add(
'ErrorHandler', // Resolve by name via container / Archetypenew ContentSecurityPolicy(), // Add middleware instance
function($request, $handler) {
// Add middleware callback
// $handler is the next middleware in the stack
// $request is the current request// Return a response
return Harvest::text('Hello World!');
}
);$request = Harvest::createRequestFromEnvironment();
$response = $dispatcher->dispatch($request);
```String names passed to the Dispatcher will resolve via the optional PSR Container and then Archetype which has a default mapping for
DecodeLabs\Harvest\Middleware
but can easily be extended with:```php
use DecodeLabs\Archetype;
use DecodeLabs\Harvest\Middleware;Archetype::map(Middleware::class, MyMiddlewareNamespace::class);
```### Fibers
Harvest uses PHP Fibers to _flatten_ the call stack within the dispatch loop - this makes for considerably less _noise_ when debugging and understanding Exception call stacks.
Instead of a call stack that grows by at least 2 frames for every Middleware instance in the queue (which gets problematic very quickly), Harvest utilises the flexbility of Fibers to break out of the stack at each call to the _next_ HTTP handler and effectively run each Middleware as if it were in a flat list, but without breaking Exception handling or any of the semantics of stacking the Middleware contexts.
### Transports
Once a Response has been generated, you can then use an instance of a Harvest
Transport
to send it to the client.Harvest currently provides a Generic Transport implementation that uses PHP's built in header and output stream functions.
```php
use DecodeLabs\Harvest;$transport = Harvest::createTransport(
// $name - a null name will default to the Generic transport
);$transport->sendResponse(
$request, $response
);exit;
```### Responses
Harvest provides easy shortcuts for creating Response instances:
```php
use DecodeLabs\Harvest;$text = Harvest::text('Hello World!'); // Text
$customText = Harvest::text('Hello World!', 201, [
'Custom-Header' => 'header-value'
]);$html = Harvest::html('
Hello World!
'); // HTML$json = Harvest::json([
'whatever-data' => 'Hello World!'
]); // JSON$xml = Harvest::xml($xmlString); // XML
$redirect = Harvest::redirect('/some/other/path'); // Redirect
$file = Harvest::stream('/path/to/file'); // Stream
$resource = Harvest::stream(Harvest::createStreamFromResource($resource)); // Stream
$generator = Harvest::generator(function() {
yield 'Custom content';
yield ' can be written';
yield ' from a generator';
}, 200, [
'Content-Type' => 'text/plain'
]);
```## Licensing
Harvest is licensed under the MIT License. See [LICENSE](./LICENSE) for the full license text.