From 29fed99ec0bd5d7d41b657c521f617b0c429e508 Mon Sep 17 00:00:00 2001
From: Sebastian Meyer
Date: Fri, 12 Jul 2024 15:29:35 +0200
Subject: [PATCH] Update documentation for QueueRequestHandler
---
.../guide/overview/queuerequesthandler.rst | 105 +++++++++
.phpdoc/guide/usage/usage.rst | 4 +-
doc/classes/OCC-PSR15-AbstractMiddleware.html | 6 +-
.../OCC-PSR15-QueueRequestHandler.html | 17 +-
doc/files/src/AbstractMiddleware.php.txt | 2 -
doc/files/src/QueueRequestHandler.php.txt | 15 +-
doc/guides/overview/index.html | 13 ++
doc/guides/overview/queuerequesthandler.html | 214 ++++++++++++++++++
doc/guides/usage/usage.html | 4 +-
src/AbstractMiddleware.php | 2 -
src/QueueRequestHandler.php | 15 +-
11 files changed, 368 insertions(+), 29 deletions(-)
diff --git a/.phpdoc/guide/overview/queuerequesthandler.rst b/.phpdoc/guide/overview/queuerequesthandler.rst
index f354dc9..8b79587 100644
--- a/.phpdoc/guide/overview/queuerequesthandler.rst
+++ b/.phpdoc/guide/overview/queuerequesthandler.rst
@@ -3,3 +3,108 @@
QueueRequestHandler
###################
+.. sidebar:: Table of Contents
+ .. contents::
+
+The `QueueRequestHandler` is the core piece of this package. It fetches incoming HTTP requests, passes them through a
+queue of middlewares and finally sends the response back to the client. It also catches any exceptions not handled by
+a middleware and turns them into a proper HTTP error response.
+
+The `QueueRequestHandler` implements the
+`Psr\Http\Server\RequestHandlerInterface `_
+following PHP-FIG's recommendation `PSR-15: HTTP Server Request Handlers `_.
+
+For a minimal working example have a look at :doc:`../usage/usage`.
+
+Properties
+==========
+
+The `QueueRequestHandler` has three **read-only** properties. They are initially set at instantiation and can be
+directly accessed from the object via magic methods (e.g. `$requestHandler->queue`).
+
+Middleware Queue
+----------------
+
+The queue of middlewares can be accessed as `QueueRequestHandler::queue` and offers a handy API to `enqueue()`,
+`dequeue()` or otherwise manipulate its contents. All middlewares must implement `Psr\Http\Server\MiddlewareInterface`.
+Have a look at :doc:`middlewarequeue` for more details.
+
+When instantiating a `QueueRequestHandler` the queue defaults to being empty. But you can optionally pass an iterable
+set of middlewares to the constructor which are then put into the queue. To demonstrate, the following examples both
+have exactly the same result.
+
+ Examples:
+
+ .. code-block:: php
+ use OCC\PSR15\QueueRequestHandler;
+
+ $middlewares = [
+ new MiddlewareOne(),
+ new MiddlewareTwo()
+ ];
+
+ $requestHandler = new QueueRequestHandler($middlewares);
+
+ .. code-block:: php
+ use OCC\PSR15\QueueRequestHandler;
+
+ $requestHandler = new QueueRequestHandler();
+
+ $requestHandler->queue->enqueue(new MiddlewareOne());
+ $requestHandler->queue->enqueue(new MiddlewareTwo());
+
+
+HTTP Server Request
+-------------------
+
+The server request is always available as `QueueRequestHandler::request`. It follows PHP-FIG's standard recommendation
+`PSR-7: HTTP Message Interfaces `_ and implements the
+`Psr\Http\Message\ServerRequestInterface `_.
+
+When instantiating a `QueueRequestHandler` the `$request` property is initially set by fetching the actual server
+request data from superglobals. The property is reset each time the request is passed through a middleware and thus
+always represents the current state of the request.
+
+HTTP Response
+-------------
+
+The response can be read as `QueueRequestHandler::response`. It also follows PHP-FIG's standard recommendation
+`PSR-7: HTTP Message Interfaces `_ and implements the
+`Psr\Http\Message\ResponseInterface `_.
+
+When instantiating a `QueueRequestHandler` the `$response` property is initially set as a blank HTTP response with
+status code `200`. The property is reset each time the response is passed through a middleware and thus
+always represents the latest state of the response.
+
+Both, request and response, use the awesome implementations of `Guzzle `_.
+
+Methods
+=======
+
+The `QueueRequestHandler` provides two public API methods, :php:method:`OCC\PSR15\QueueRequestHandler::handle()` and
+:php:method:`OCC\PSR15\QueueRequestHandler::respond()`. As their names suggest, the former handles the server request
+while the latter sends the response back to the client. Invoking the request handler object directly does the same as
+calling the `handle()` method.
+
+Handling a Server Request
+-------------------------
+
+After adding at least one middleware to the queue, you can start handling a request by simply calling
+:php:method:`OCC\PSR15\QueueRequestHandler::handle()`. Optionally, you can pass a request object as argument, but since
+the actual server request was already fetched in the constructor and will be used by default, most of the time you
+don't need to. All request objects must implement `Psr\Http\Message\ServerRequestInterface`.
+
+The `handle()` method returns the final response after passing it through all middlewares. The response object always
+implements `Psr\Http\Message\ResponseInterface`.
+
+In case of an error the request handler catches any exception and creates a response with the exception code as status
+code (if it's within the valid range of HTTP status codes, otherwise it's set to `500 (Internal Server Error)`), and
+the exception message as body.
+
+Sending the Response
+--------------------
+
+Sending the final response to the client is as easy as calling :php:method:`OCC\PSR15\QueueRequestHandler::respond()`.
+Optionally, you can provide an exit code as argument (an integer in the range `0` to `254`). If you do so, script
+execution is stopped after sending out the response and the given exit status is set. The status `0` means the request
+was handled successfully, every other status is considered an error.
diff --git a/.phpdoc/guide/usage/usage.rst b/.phpdoc/guide/usage/usage.rst
index cb265ff..aedb075 100644
--- a/.phpdoc/guide/usage/usage.rst
+++ b/.phpdoc/guide/usage/usage.rst
@@ -20,7 +20,7 @@ The abstract middleware already implements a complete middleware, but it will ju
anything. In order to have it do something, we need to implement our own :php:method:`OCC\PSR15\AbstractMiddleware::processRequest()`
or :php:method:`OCC\PSR15\AbstractMiddleware::processResponse()` method, or both of them.
-The logic here is the same as with every `PSR-15: HTTP Server Request Handler `_
+The logic here is the same as with every `PSR-15: HTTP Server Request Handlers `_
middleware: The request gets passed through all middlewares' `processRequest()` methods in order of their addition to
the queue, then a response is created and passed through all `processResponse()` methods, **but in reverse order**! So
the first middleware in the queue gets the request first, but the response last.
@@ -149,7 +149,7 @@ Diving Deeper
=============
To familiarize yourself with the FIFO principle of the middleware queue, you can try to exchange the two lines adding
-the middlewares to the queue, i.e. adding `MiddlewareTwo` first and `MiddlewareOne` second. This will result in an HTTP
+the middlewares to the queue, i.e. add `MiddlewareTwo` first and `MiddlewareOne` second. This will result in an HTTP
response with status code `500 (Internal Server Error)`.
This is exactly what we intended: Have a look at `MiddlewareTwo::processResponse()` again! If `$lastMiddlewarePassed`
diff --git a/doc/classes/OCC-PSR15-AbstractMiddleware.html b/doc/classes/OCC-PSR15-AbstractMiddleware.html
index 18e34d9..ca220e4 100644
--- a/doc/classes/OCC-PSR15-AbstractMiddleware.html
+++ b/doc/classes/OCC-PSR15-AbstractMiddleware.html
@@ -298,9 +298,9 @@
Allow the middleware to be invoked directly.
@@ -310,8 +310,6 @@
final __invoke(ServerRequestInterface $request, RequestHandlerInterface $handler) : ResponseInterface
diff --git a/doc/classes/OCC-PSR15-QueueRequestHandler.html b/doc/classes/OCC-PSR15-QueueRequestHandler.html
index 4868c66..08ce623 100644
--- a/doc/classes/OCC-PSR15-QueueRequestHandler.html
+++ b/doc/classes/OCC-PSR15-QueueRequestHandler.html
@@ -442,9 +442,9 @@
Create a queue-based PSR-15 HTTP Server Request Handler.
@@ -490,9 +490,9 @@
Allow the request handler to be invoked directly.
@@ -502,8 +502,6 @@
__invoke([ServerRequestInterface|null $request = null ]) : ResponseInterface
@@ -606,9 +604,9 @@
Return the current response to the client.
@@ -630,7 +628,8 @@
: int|null
= null
- Exit code after sending out the response or NULL to continue
+ Exit status after sending out the response or NULL to continue
+Must be in the range 0 to 254. The status 0 is used to terminate the program successfully.
diff --git a/doc/files/src/AbstractMiddleware.php.txt b/doc/files/src/AbstractMiddleware.php.txt
index 6577645..451b1cd 100644
--- a/doc/files/src/AbstractMiddleware.php.txt
+++ b/doc/files/src/AbstractMiddleware.php.txt
@@ -99,8 +99,6 @@ abstract class AbstractMiddleware implements MiddlewareInterface
* @param RequestHandler $handler The request handler to delegate to
*
* @return Response The response object
- *
- * @api
*/
final public function __invoke(ServerRequest $request, RequestHandler $handler): Response
{
diff --git a/doc/files/src/QueueRequestHandler.php.txt b/doc/files/src/QueueRequestHandler.php.txt
index e29a280..5dab177 100644
--- a/doc/files/src/QueueRequestHandler.php.txt
+++ b/doc/files/src/QueueRequestHandler.php.txt
@@ -120,7 +120,6 @@ class QueueRequestHandler implements RequestHandler
$exception->getMessage()
)
);
- $this->respond(1);
}
}
return $this->response;
@@ -129,7 +128,9 @@ class QueueRequestHandler implements RequestHandler
/**
* Return the current response to the client.
*
- * @param ?int $exitCode Exit code after sending out the response or NULL to continue
+ * @param ?int $exitCode Exit status after sending out the response or NULL to continue
+ *
+ * Must be in the range 0 to 254. The status 0 is used to terminate the program successfully.
*
* @return void
*
@@ -166,6 +167,14 @@ class QueueRequestHandler implements RequestHandler
}
echo $this->response->getBody();
if (!is_null($exitCode)) {
+ $options = [
+ 'options' => [
+ 'default' => 1,
+ 'min_range' => 0,
+ 'max_range' => 254
+ ]
+ ];
+ $exitCode = filter_var($exitCode, FILTER_VALIDATE_INT, $options);
exit($exitCode);
}
}
@@ -226,8 +235,6 @@ class QueueRequestHandler implements RequestHandler
* @param ?ServerRequest $request The PSR-7 server request to handle
*
* @return Response A PSR-7 compatible HTTP response
- *
- * @api
*/
public function __invoke(?ServerRequest $request = null): Response
{
diff --git a/doc/guides/overview/index.html b/doc/guides/overview/index.html
index 4d904a4..b57b8ba 100644
--- a/doc/guides/overview/index.html
+++ b/doc/guides/overview/index.html
@@ -171,7 +171,20 @@ in other projects.
QueueRequestHandler
+
diff --git a/doc/guides/overview/queuerequesthandler.html b/doc/guides/overview/queuerequesthandler.html
index 8eee82c..a57fd83 100644
--- a/doc/guides/overview/queuerequesthandler.html
+++ b/doc/guides/overview/queuerequesthandler.html
@@ -153,6 +153,220 @@
QueueRequestHandler
+
+
+
+
+
+
The QueueRequestHandler
+ is the core piece of this package. It fetches incoming HTTP requests, passes them through a
+queue of middlewares and finally sends the response back to the client. It also catches any exceptions not handled by
+a middleware and turns them into a proper HTTP error response.
+
+
+
The QueueRequestHandler
+ implements the
+Psr\Http\Server\RequestHandlerInterface
+following PHP-FIG's recommendation PSR-15: HTTP Server Request Handlers.
+
+
+
For a minimal working example have a look at Usage.
+
+
+
Properties
+
+
+
The QueueRequestHandler
+ has three read-only
+ properties. They are initially set at instantiation and can be
+directly accessed from the object via magic methods (e.g. $requestHandler->queue
+).
+
+
+
Middleware Queue
+
+
+
The queue of middlewares can be accessed as QueueRequestHandler::queue
+ and offers a handy API to enqueue()
+,
+dequeue()
+ or otherwise manipulate its contents. All middlewares must implement Psr\Http\Server\MiddlewareInterface
+.
+Have a look at MiddlewareQueue for more details.
+
+
+
When instantiating a QueueRequestHandler
+ the queue defaults to being empty. But you can optionally pass an iterable
+set of middlewares to the constructor which are then put into the queue. To demonstrate, the following examples both
+have exactly the same result.
+
+
+ Examples:
+use OCC\PSR15\QueueRequestHandler;
+
+$middlewares = [
+ new MiddlewareOne(),
+ new MiddlewareTwo()
+];
+
+$requestHandler = new QueueRequestHandler($middlewares);
+use OCC\PSR15\QueueRequestHandler;
+
+$requestHandler = new QueueRequestHandler();
+
+$requestHandler->queue->enqueue(new MiddlewareOne());
+$requestHandler->queue->enqueue(new MiddlewareTwo());
+
+
+
+
+
+
HTTP Server Request
+
+
+
The server request is always available as QueueRequestHandler::request
+. It follows PHP-FIG's standard recommendation
+PSR-7: HTTP Message Interfaces and implements the
+Psr\Http\Message\ServerRequestInterface.
+
+
+
When instantiating a QueueRequestHandler
+ the $request
+ property is initially set by fetching the actual server
+request data from superglobals. The property is reset each time the request is passed through a middleware and thus
+always represents the current state of the request.
+
+
+
+
+
HTTP Response
+
+
+
The response can be read as QueueRequestHandler::response
+. It also follows PHP-FIG's standard recommendation
+PSR-7: HTTP Message Interfaces and implements the
+Psr\Http\Message\ResponseInterface.
+
+
+
When instantiating a QueueRequestHandler
+ the $response
+ property is initially set as a blank HTTP response with
+status code 200
+. The property is reset each time the response is passed through a middleware and thus
+always represents the latest state of the response.
+
+
+
Both, request and response, use the awesome implementations of Guzzle.
+
+
+
+
+
+
+
Methods
+
+
+
The QueueRequestHandler
+ provides two public API methods, QueueRequestHandler::handle()
+ and
+QueueRequestHandler::respond()
+. As their names suggest, the former handles the server request
+while the latter sends the response back to the client. Invoking the request handler object directly does the same as
+calling the handle()
+ method.
+
+
+
Handling a Server Request
+
+
+
After adding at least one middleware to the queue, you can start handling a request by simply calling
+QueueRequestHandler::handle()
+. Optionally, you can pass a request object as argument, but since
+the actual server request was already fetched in the constructor and will be used by default, most of the time you
+don't need to. All request objects must implement Psr\Http\Message\ServerRequestInterface
+.
+
+
+
The handle()
+ method returns the final response after passing it through all middlewares. The response object always
+implements Psr\Http\Message\ResponseInterface
+.
+
+
+
In case of an error the request handler catches any exception and creates a response with the exception code as status
+code (if it's within the valid range of HTTP status codes, otherwise it's set to 500 (Internal Server Error)
+), and
+the exception message as body.
+
+
+
+
+
Sending the Response
+
+
+
Sending the final response to the client is as easy as calling QueueRequestHandler::respond()
+.
+Optionally, you can provide an exit code as argument (an integer in the range 0
+ to 254
+). If you do so, script
+execution is stopped after sending out the response and the given exit status is set. The status 0
+ means the request
+was handled successfully, every other status is considered an error.
+
+
+
+
+
diff --git a/doc/guides/usage/usage.html b/doc/guides/usage/usage.html
index a1b3555..60926f5 100644
--- a/doc/guides/usage/usage.html
+++ b/doc/guides/usage/usage.html
@@ -205,7 +205,7 @@ or
- The logic here is the same as with every PSR-15: HTTP Server Request Handler
+
The logic here is the same as with every PSR-15: HTTP Server Request Handlers
middleware: The request gets passed through all middlewares' processRequest()
methods in order of their addition to
the queue, then a response is created and passed through all processResponse()
@@ -348,7 +348,7 @@ $requestHandler->respond();
To familiarize yourself with the FIFO principle of the middleware queue, you can try to exchange the two lines adding
-the middlewares to the queue, i.e. adding MiddlewareTwo
+the middlewares to the queue, i.e. add MiddlewareTwo
first and MiddlewareOne
second. This will result in an HTTP
response with status code 500 (Internal Server Error)
diff --git a/src/AbstractMiddleware.php b/src/AbstractMiddleware.php
index 6577645..451b1cd 100644
--- a/src/AbstractMiddleware.php
+++ b/src/AbstractMiddleware.php
@@ -99,8 +99,6 @@ abstract class AbstractMiddleware implements MiddlewareInterface
* @param RequestHandler $handler The request handler to delegate to
*
* @return Response The response object
- *
- * @api
*/
final public function __invoke(ServerRequest $request, RequestHandler $handler): Response
{
diff --git a/src/QueueRequestHandler.php b/src/QueueRequestHandler.php
index e29a280..5dab177 100644
--- a/src/QueueRequestHandler.php
+++ b/src/QueueRequestHandler.php
@@ -120,7 +120,6 @@ class QueueRequestHandler implements RequestHandler
$exception->getMessage()
)
);
- $this->respond(1);
}
}
return $this->response;
@@ -129,7 +128,9 @@ class QueueRequestHandler implements RequestHandler
/**
* Return the current response to the client.
*
- * @param ?int $exitCode Exit code after sending out the response or NULL to continue
+ * @param ?int $exitCode Exit status after sending out the response or NULL to continue
+ *
+ * Must be in the range 0 to 254. The status 0 is used to terminate the program successfully.
*
* @return void
*
@@ -166,6 +167,14 @@ class QueueRequestHandler implements RequestHandler
}
echo $this->response->getBody();
if (!is_null($exitCode)) {
+ $options = [
+ 'options' => [
+ 'default' => 1,
+ 'min_range' => 0,
+ 'max_range' => 254
+ ]
+ ];
+ $exitCode = filter_var($exitCode, FILTER_VALIDATE_INT, $options);
exit($exitCode);
}
}
@@ -226,8 +235,6 @@ class QueueRequestHandler implements RequestHandler
* @param ?ServerRequest $request The PSR-7 server request to handle
*
* @return Response A PSR-7 compatible HTTP response
- *
- * @api
*/
public function __invoke(?ServerRequest $request = null): Response
{