Action–domain–responder (ADR) is a software architectural pattern that was proposed by Paul M. Jones[1] as a refinement of Model–view–controller (MVC) that is better suited for web applications. ADR was devised to match the request-response flow of HTTP communications more closely than MVC, which was originally designed for desktop software applications.
from Wikipedia
This bundle simplifies the setup of the ADR in a Symfony 5.0 project.
- 1.x version (stable version) : Recommended for all projects using Symfony 3.4.
- 2.x version (stable version) : Recommended for all projects using Symfony 4.4.
- 3.x version (stable version) : Recommended for all projects using Symfony 5.0 or newer.
- PHP : version 7.2 minimum
- Symfony : version 5.0 minimum
composer require berenger/adr-bundle:^3.0
Use in the reponse's header : Access-Control-Allow-Origin
update the file : config/service.yaml
parameters:
...
cors: "https://url.service"
...
update the file : config/bundles.php
<?php
return [
...
AdrBundle\AdrBundle::class => ['all' => true],
...
];
update the file : config/service.yaml
services:
_defaults:
autowire: true
autoconfigure: true
public: true
post:
path: /posts/{id}
controller: App\Controller\ViewPostAction
methods: ["GET"]
defaults:
responder: App\Responder\ViewPostResponder
The action must return an associative array that will be pass to the responder __invoke
method.
Each key of the array must match an argument of the responder __invoke
method signature,
otherwise an exception will be thrown. The order of the arguments in the array is not important.
<?php
namespace App\Controller;
use App\Entity\Post;
use Doctrine\ORM\EntityNotFoundException;
class ViewPostAction
{
public function __invoke(int $id)
{
$postRepository = $this->getDoctrine()->getRepository(Post::class);
$post = $postRepository->findOneById($id);
if (!$post) {
throw new EntityNotFoundException('Post not found');
}
return [
'post' => $post,
];
}
}
The responder can either:
- directly return an instance of
Symfony\Component\HttpFoundation\Response
(e.g. when you return a response containing HTML generated with Twig) - an array of data to be serialized in the response (mostly the case when you're building an API that returns Json or XML). In that case you can specify serialization groups.
<?php
namespace App\Responder;
use App\Entity\Post;
class ViewPostResponder
{
/**
* @param Post $post
* @return array
*/
public function __invoke(Post $post)
{
return [
'data' => [
'post' => $post,
],
'serialization_groups' => 'view',
];
}
}
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Serializer\Annotation\Groups;
class Post
{
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer", options={"unsigned"=true})
* @Groups({"always"})
*/
private $id;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"list","view"})
*/
private $title;
/**
* @ORM\Column(type="string", length=255)
* @Groups({"view"})
*/
private $content;
...
}
accept:application/json
accept:application/xml