Optimized REST API and tests

This commit is contained in:
Kevin Frantz
2019-02-19 19:36:02 +01:00
parent cbb1c76640
commit 1beae0cdc0
19 changed files with 183 additions and 132 deletions

View File

@@ -1,6 +0,0 @@
# REST API Controller
The controllers use the [FOSRestBundle](https://symfony.com/doc/master/bundles/FOSRestBundle/index.html).
## Workflow
The abstract workflow of the REST API controllers for a singular entity looks like this:
![REST API Workflow](.meta/workflow.svg)
Special actions, e.g. lists are not shown in this diagram. This diagram also shows downstream procedures, to remember to implement them. Feel free to remove them from the diagram, as soon as they are documented somewhere else.

View File

Before

Width:  |  Height:  |  Size: 108 KiB

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -1,6 +1,6 @@
<?php
namespace Infinito\Controller\API\Meta;
namespace Infinito\Controller\API\Rest;
use Infinito\Controller\API\AbstractAPIController;
use Symfony\Component\HttpFoundation\Request;
@@ -11,7 +11,7 @@ use Symfony\Component\HttpFoundation\Response;
*
* @todo Implement!
*/
class RightApiController extends AbstractAPIController
final class HeredityController extends AbstractAPIController
{
public function read(Request $request, $identifier): Response
{

View File

@@ -1,6 +1,6 @@
<?php
namespace Infinito\Controller\API\Meta;
namespace Infinito\Controller\API\Rest;
use Infinito\Controller\API\AbstractAPIController;
use Symfony\Component\HttpFoundation\Request;
@@ -11,7 +11,7 @@ use Symfony\Component\HttpFoundation\Response;
*
* @todo Implement!
*/
class LawApiController extends AbstractAPIController
final class LawController extends AbstractAPIController
{
public function read(Request $request, $identifier): Response
{

View File

@@ -1,6 +1,6 @@
<?php
namespace Infinito\Controller\API\Meta;
namespace Infinito\Controller\API\Rest;
use Infinito\Controller\API\AbstractAPIController;
use Symfony\Component\HttpFoundation\Request;
@@ -11,7 +11,7 @@ use Symfony\Component\HttpFoundation\Response;
*
* @todo Implement!
*/
class MemberApiController extends AbstractAPIController
final class MemberController extends AbstractAPIController
{
public function read(Request $request, $identifier): Response
{

View File

@@ -0,0 +1,24 @@
# REST API Controller
The controllers use the [FOSRestBundle](https://symfony.com/doc/master/bundles/FOSRestBundle/index.html).
## Url Scheme
The scheme for the rest api is the following:
| Url | Methods | Function |
|---|---|---|
| api/rest/{entity}.{format} | HEAD | Returns the create information for a specific entity |
| api/rest/{entity}.{format} | POST | Creates a specific entity and returns it. |
| api/rest/{entity}/{uri}.{format} | GET | Returns a specific entity. Including all actions |
| api/rest/{entity}/{uri}/{action}.{format} | GET | Returns the result for an action of an specific entity. |
| api/rest/{entity}/{uri}.{format} | PUT, PATCH | Updates a specific entity and returns it. |
| api/rest/{entity}/{uri}.{format} | DELETE | Deletes a specific entity|
If an concrete entity doesn't implement an method it should redirect to the connected entity which is responsible for this method.
In the future it would make sense to implement [more methods](https://de.wikipedia.org/wiki/Representational_State_Transfer#Umsetzung).
The standard format of an entity MUST be JSON.
## Workflow
The abstract workflow of the REST API controllers for a singular entity looks like this:
![REST API Workflow](.meta/workflow.svg)
Special actions, e.g. lists are not shown in this diagram. This diagram also shows downstream procedures, to remember to implement them. Feel free to remove them from the diagram, as soon as they are documented somewhere else.

View File

@@ -1,6 +1,6 @@
<?php
namespace Infinito\Controller\API\Meta;
namespace Infinito\Controller\API\Rest;
use Infinito\Controller\API\AbstractAPIController;
use Symfony\Component\HttpFoundation\Request;
@@ -11,7 +11,7 @@ use Symfony\Component\HttpFoundation\Response;
*
* @todo Implement!
*/
class HeredityApiController extends AbstractAPIController
final class RightController extends AbstractAPIController
{
public function read(Request $request, $identifier): Response
{

View File

@@ -1,6 +1,6 @@
<?php
namespace Infinito\Controller\API\Source;
namespace Infinito\Controller\API\Rest;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
@@ -18,20 +18,19 @@ use Infinito\DBAL\Types\Meta\Right\LayerType;
* @see https://symfony.com/blog/new-in-symfony-4-1-internationalized-routing
* @Route(
* {
* "en":"/source/{identity}.{_format}",
* "de":"/quelle/{identity}.{_format}",
* "eo":"/fonto/{identity}.{_format}",
* "es":"/fontanar/{identity}.{_format}",
* "nl":"/bron/{identity}.{_format}"
* "en":"/api/rest/source/{identity}.{_format}",
* "de":"/api/rest/quelle/{identity}.{_format}",
* "eo":"/api/rest/fonto/{identity}.{_format}",
* "es":"/api/rest/fontanar/{identity}.{_format}",
* "nl":"/api/rest/bron/{identity}.{_format}"
* },
* defaults={
* "identity"="",
* "_format"="json"
* } ,
* name="source_"
* }
* )
*/
class SourceApiController extends AbstractAPIController
final class SourceController extends AbstractAPIController
{
/**
* @Route(

View File

@@ -12,7 +12,7 @@ use Infinito\DBAL\Types\Meta\Right\CRUDType;
final class ActionType extends CRUDType
{
/**
* @var string
* @var string this action executes an entity
*/
const EXECUTE = 'execute';

View File

@@ -10,20 +10,22 @@ use Symfony\Component\HttpFoundation\Request;
*/
final class ActionHttpMethodMap extends AbstractMap implements ActionHttpMethodMapInterface
{
/**
* @var array
*/
const ACTION_HTTP_METHOD_MAP = [
ActionType::READ => [
Request::METHOD_GET,
],
ActionType::CREATE => [
Request::METHOD_POST,
Request::METHOD_GET,
Request::METHOD_HEAD,
],
ActionType::UPDATE => [
Request::METHOD_PUT,
Request::METHOD_GET,
Request::METHOD_PATCH,
],
ActionType::DELETE => [
Request::METHOD_GET,
Request::METHOD_DELETE,
],
ActionType::EXECUTE => [

View File

@@ -13,11 +13,11 @@ use Infinito\Entity\Source\AbstractSource;
use Infinito\Exception\NotSetException;
use Infinito\Repository\RepositoryInterface;
use Infinito\Entity\Source\SourceInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Infinito\Attribut\ClassAttribut;
use Infinito\Exception\AllreadyDefinedException;
use Infinito\Domain\RequestManagement\Right\RequestedRightInterface;
use Infinito\Domain\RepositoryManagement\LayerRepositoryFactoryService;
use Infinito\Exception\EntityNotFoundHttpException;
/**
* @author kevinfrantz
@@ -51,12 +51,12 @@ class RequestedEntity extends AbstractEntity implements RequestedEntityInterface
/**
* @param EntityInterface|null $entity
*
* @throws NotFoundHttpException
* @throws EntityNotFoundHttpException
*/
private function validateLoadedEntity(?EntityInterface $entity): void
{
if (!$entity) {
throw new NotFoundHttpException('Entity with {id:"'.$this->id.'",slug:"'.$this->slug.'"} not found');
throw new EntityNotFoundHttpException('Entity with {id:"'.$this->id.'",slug:"'.$this->slug.'"} not found');
}
}
@@ -97,7 +97,7 @@ class RequestedEntity extends AbstractEntity implements RequestedEntityInterface
}
/**
* @throws NotFoundHttpException
* @throws NotSetException
*/
private function validateLayerRepositoryFactoryService(): void
{

View File

@@ -0,0 +1,12 @@
<?php
namespace Infinito\Exception;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* @author kevinfrantz
*/
final class EntityNotFoundHttpException extends NotFoundHttpException
{
}