PHP micro-framework for small REST or HTTP RPC services. Built and open sourced by J Sainsbury plc.
The framework is basically a wrapper for the Slim micro-framework in PHP, but works only with a more structured application.
It relies on Slim 3.
Version 1.x.x is an LTS version with support for PHP 5.5. Version 2.0.0 and subsequent require PHP 7.
See the sample application for an example of how to use it. The sample application is used by the automated tests as well, so will be up-to-date.
Standards Compliance
The framework aims to comply with the PSR-3 standard for interchangable loggers, the PSR-7 standard for interchangable HTTP request and response objects, the Container-Interop standard for interchangable Dependency Injection Containers, and with semantic versioning in its release numbers.
Controllers and Dependency Injection
This is what a controller should look like:
<?php
namespace MyNamespace;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
class EmptyController
{
public function emptyAction(ServerRequestInterface $request, ResponseInterface $response)
{
return $response;
}
}
Controllers must be objects, not closures. No abstract controller is provided - controllers should be stand-alone objects with no inheritance. Controllers will be retrieved from a dependency injection container.
Your routing config will map a route pattern to the service ID of the controller. Provide a Container Interop container with your controllers in it. A standards-compliant Pimple 3 wrapper is used in the example index file provided.
Try looking at the example routing file and typical dependency injection configuration for a clear example of this. Your routing config file may be a .php 'return array' file, a JSON file, a YAML file or a .ini file.
Controller Actions - acceptable return types
Controller actions must return a PSR-7 HTTP Response object. The parametric response is a Zend Diactoros JsonResponse
.
Middlewares
To use middlewares in the framework, call Sainsburys\HttpService\Application::middlewareManager()
. You
can add your own implementations of the BeforeMiddleware
and AfterMiddleware
interfaces to a list. They
will run accordingly.
Exception Handling
Throwing an uncaught exception from a controller will cause a response with the exception details encoded in JSON. The
status code will usually be 500. If the exception implements
Sainsburys\HttpService\Components\ErrorHandling\Exceptions\ExceptionWithHttpStatus
, the status code on the
exception will be used.
If you wish to implement your own error handler, for example if you don't want stack traces being visible in the
response in production, call Sainsburys\HttpService\Application::useThisErrorController()'
in your
index.php
file, and give it a different error controller it can use. Sainsburys\HttpService\Components\ErrorHandling\ErrorController\ProductionExternalisedErrorController
is provided if you wish to use an error controller with less verbose output.
Error Logging
Your error controller will be passed a Psr\Log\LoggerInterface
, which by default will be a
Psr\Log\NullLogger
. This does nothing. To do error logging, call Application::setLogger()
. You will
need a PSR-3 compliant logger for this. We suggest that you pass your choice of logging object into your other
controllers or other classes as well, where logging is required. You can do this when you configure the dependencies of
your controller in your DI container. The Monolog logging tool may be a good
choice of logging library in PHP if you are looking for ideas.
Use Composer.
"require": {
"sainsburys/sainsburys-http-service": "*"
}
You may also need to require "slim/slim": "^3.0.0-RC3"
, depending on your project's composer settings. This will
change shortly.
Check the project out, run Composer, and type ./bin/test
to run all the tests. Read
that shell script for specific test commands.
- PHPSpec is used for unit testing;
- Behat is used to provide service-level behavioural tests, with an example application using the framework, testing the application object inline;
- PHPUnit is used for a small number of service-level tests
- A few Behat tests will also run in conjunction with a webserver, with real HTTP requests provided by Guzzle.