diff --git a/config/autoload/errorhandler.local.php.dist b/config/autoload/errorhandler.local.php.dist index 552b6ffb..6dea98cb 100644 --- a/config/autoload/errorhandler.local.php.dist +++ b/config/autoload/errorhandler.local.php.dist @@ -1,4 +1,6 @@ [ 'routes_whitelist' => [ Action\AuthenticateAction::class, + Action\HealthAction::class, Action\ShortUrl\SingleStepCreateShortUrlAction::class, ], diff --git a/module/Rest/config/dependencies.config.php b/module/Rest/config/dependencies.config.php index ab2d9901..27e86a35 100644 --- a/module/Rest/config/dependencies.config.php +++ b/module/Rest/config/dependencies.config.php @@ -18,6 +18,7 @@ return [ ApiKeyService::class => ConfigAbstractFactory::class, Action\AuthenticateAction::class => ConfigAbstractFactory::class, + Action\HealthAction::class => Action\HealthActionFactory::class, Action\ShortUrl\CreateShortUrlAction::class => ConfigAbstractFactory::class, Action\ShortUrl\SingleStepCreateShortUrlAction::class => ConfigAbstractFactory::class, Action\ShortUrl\EditShortUrlAction::class => ConfigAbstractFactory::class, diff --git a/module/Rest/config/routes.config.php b/module/Rest/config/routes.config.php index a937bc42..b3586fda 100644 --- a/module/Rest/config/routes.config.php +++ b/module/Rest/config/routes.config.php @@ -3,12 +3,11 @@ declare(strict_types=1); namespace Shlinkio\Shlink\Rest; -use Shlinkio\Shlink\Rest\Action; - return [ 'routes' => [ Action\AuthenticateAction::getRouteDef(), + Action\HealthAction::getRouteDef(), // Short codes Action\ShortUrl\CreateShortUrlAction::getRouteDef([ diff --git a/module/Rest/src/Action/AbstractRestAction.php b/module/Rest/src/Action/AbstractRestAction.php index 21e15d66..a9c449c4 100644 --- a/module/Rest/src/Action/AbstractRestAction.php +++ b/module/Rest/src/Action/AbstractRestAction.php @@ -14,6 +14,7 @@ abstract class AbstractRestAction implements RequestHandlerInterface, RequestMet { protected const ROUTE_PATH = ''; protected const ROUTE_ALLOWED_METHODS = []; + protected const ROUTE_CAN_BE_VERSIONED = true; /** @var LoggerInterface */ protected $logger; @@ -30,6 +31,7 @@ abstract class AbstractRestAction implements RequestHandlerInterface, RequestMet 'middleware' => array_merge($prevMiddleware, [static::class], $postMiddleware), 'path' => static::ROUTE_PATH, 'allowed_methods' => static::ROUTE_ALLOWED_METHODS, + 'can_be_versioned' => static::ROUTE_CAN_BE_VERSIONED, ]; } } diff --git a/module/Rest/src/Action/AuthenticateAction.php b/module/Rest/src/Action/AuthenticateAction.php index 62a21e99..e310e48f 100644 --- a/module/Rest/src/Action/AuthenticateAction.php +++ b/module/Rest/src/Action/AuthenticateAction.php @@ -12,6 +12,7 @@ use Shlinkio\Shlink\Rest\Service\ApiKeyServiceInterface; use Shlinkio\Shlink\Rest\Util\RestUtils; use Zend\Diactoros\Response\JsonResponse; +/** @deprecated */ class AuthenticateAction extends AbstractRestAction { protected const ROUTE_PATH = '/authenticate'; diff --git a/module/Rest/src/Action/HealthAction.php b/module/Rest/src/Action/HealthAction.php new file mode 100644 index 00000000..35af83fa --- /dev/null +++ b/module/Rest/src/Action/HealthAction.php @@ -0,0 +1,52 @@ +conn = $conn; + $this->options = $options; + } + + /** + * Handles a request and produces a response. + * + * May call other collaborating code to generate the response. + */ + public function handle(ServerRequestInterface $request): ResponseInterface + { + $connected = $this->conn->ping(); + $statusCode = $connected ? self::STATUS_OK : self::STATUS_SERVICE_UNAVAILABLE; + + return new JsonResponse([ + 'status' => $connected ? 'pass' : 'fail', + 'version' => $this->options->getVersion(), + 'links' => [ + 'about' => 'https://shlink.io', + 'project' => 'https://github.com/shlinkio/shlink', + ], + ], $statusCode, ['Content-type' => self::HEALTH_CONTENT_TYPE]); + } +} diff --git a/module/Rest/src/Action/HealthActionFactory.php b/module/Rest/src/Action/HealthActionFactory.php new file mode 100644 index 00000000..fdd85ba8 --- /dev/null +++ b/module/Rest/src/Action/HealthActionFactory.php @@ -0,0 +1,19 @@ +get(EntityManager::class); + $options = $container->get(AppOptions::class); + $logger = $container->get('Logger_Shlink'); + return new HealthAction($em->getConnection(), $options, $logger); + } +} diff --git a/module/Rest/src/ConfigProvider.php b/module/Rest/src/ConfigProvider.php index c6afdcfe..a951161b 100644 --- a/module/Rest/src/ConfigProvider.php +++ b/module/Rest/src/ConfigProvider.php @@ -5,10 +5,12 @@ namespace Shlinkio\Shlink\Rest; use Zend\Config\Factory; use Zend\Stdlib\Glob; +use function sprintf; class ConfigProvider { - const ROUTES_PREFIX = '/rest/v{version:1}'; + private const ROUTES_PREFIX = '/rest'; + private const ROUTES_VERSION_PARAM = '/v{version:1}'; public function __invoke() { @@ -23,7 +25,14 @@ class ConfigProvider // Prepend the routes prefix to every path foreach ($routes as $key => $route) { - $routes[$key]['path'] = self::ROUTES_PREFIX . $route['path']; + ['can_be_versioned' => $routeCanBeVersioned, 'path' => $path] = $route; + $routes[$key]['path'] = sprintf( + '%s%s%s', + self::ROUTES_PREFIX, + $routeCanBeVersioned ? self::ROUTES_VERSION_PARAM : '', + $path + ); + unset($routes[$key]['can_be_versioned']); } return $config;