This library provides all the tools for defining REST APIs and validate requests and responses.
composer require everlution/simple-rest-api
# if you are using the JsonSchemaValidator
composer require justinrainbow/json-schema
In order to define a new API you need to implement the Everlution\SimpleRestApi\Api\ApiInterface
.
If you are implementing an API that is going to be validated with JSON Schema you can implement the JsonSchemaApiInterface
.
<?php
namespace App\Api\Sms;
use App\ApiBusinessLogic\Sms\SendApiBusinessLogic;
use App\JsonSchema\Api\Sms\Send\RequestJsonSchema;
use App\JsonSchema\Api\Sms\Send\ResponseJsonSchema;
use Everlution\SimpleRestApi\Api\AbstractApi;
use Everlution\SimpleRestApi\Api\JsonSchemaApiInterface;
use Everlution\SimpleRestApi\ApiRequestHandler\DefaultApiRequestHandler;
use Everlution\SimpleRestApi\ApiValidator\JsonSchemaApiValidator;
use Symfony\Component\HttpFoundation\Request;
class SendApi extends AbstractApi implements JsonSchemaApiInterface
{
private $requestJsonSchema;
private $responseJsonSchema;
public function __construct(
JsonSchemaApiValidator $apiValidator,
DefaultApiRequestHandler $apiRequestHandler,
SendApiBusinessLogic $apiBusinessLogic,
RequestJsonSchema $requestJsonSchema,
ResponseJsonSchema $responseJsonSchema
) {
parent::__construct($apiValidator, $apiRequestHandler, $apiBusinessLogic);
$this->requestJsonSchema = $requestJsonSchema;
$this->responseJsonSchema = $responseJsonSchema;
}
public function getTitle(): string
{
return 'SMS Send';
}
public function isDeprecated(): bool
{
return false;
}
public static function getMethods(): array
{
return [Request::METHOD_POST];
}
public static function getRoutesPaths(): array
{
return [
'/sms/send',
];
}
public function isEnabled(): bool
{
return true;
}
public function getStatusCodes(): array
{
return parent::getStatusCodes() + [401 => 'Unauthorized'];
}
public function getRequestJsonSchema(): string
{
return $this->requestJsonSchema->generate();
}
public function getResponseJsonSchema(): string
{
return $this->responseJsonSchema->generate();
}
}
This is the service that is in charge to do validation of the request and response and execute the business logic.
The library provides a default handler Everlution\SimpleRestApi\ApiRequestHandler\DefaultApiRequestHandler
.
<?php
namespace App\JsonSchema\Api\Sms\Send;
class RequestJsonSchema
{
public function toArray(): array
{
return [
'type' => 'object',
'properties' => [
'number' => [
'type' => 'string',
'description' => 'The phone number',
],
'text' => [
'type' => 'string',
'description' => 'The content of the message',
'maxLength' => 255
]
]
];
}
public function generate(): string
{
return json_encode($this->toArray());
}
}
This is the service that define what the API is suppose to do.
<?php
namespace App\ApiBusinessLogic\Sms;
use Everlution\SimpleRestApi\Api\ApiInterface;
use Everlution\SimpleRestApi\ApiBusinessLogic\ApiBusinessLogicInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
class SendApiBusinessLogic implements ApiBusinessLogicInterface
{
public function execute(ApiInterface $api, Request $request): Response
{
// Logic here
}
}
Same thing for the Response JSON Schema
Add this file to config/routes.php
<?php
use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
use App\Api\Sms;
$apis = [
Sms\SendApi::class,
// ... other APIs
];
return function (RoutingConfigurator $routes) use ($apis) {
foreach ($apis as $api) {
$i = 0;
foreach ($api::getRoutesPaths() as $routePath) {
$pathName = sprintf('%s_%s', str_replace('\\', '_', $api), $i);
$routes
->add($pathName, $routePath)
->controller([$api, 'sendResponse'])
->methods($api::getMethods());
$i++;
}
}
};
And then you need to add this to config/services.yaml
in order to make the framework recognize the API as a controller.
_instanceof:
Everlution\SimpleRestApi\Api\ApiInterface:
tags: ['controller.service_arguments']