Buongiorno a tutti. Sono Mirko Benedetti, un esperto informatico nonché copywriter e oggi parliamo di Symfony 7 come REST API, in questo completo ed esaustivo tutorial.

La prima cosa che dovrete fare per completare questo tutorial sarà quella di installare PHP e MySQL nella vostra piattaforma. Io vi consiglio Linux come piattaforma, in questo caso questo tutorial è basato su Ubuntu Linux.
Ecco qualche guida su come installare sia PHP, MySQL che Symfony sulla vostra piattaforma:
In particolare dovrete installare Composer e la CLI di Symfony, poi dovrete creare il progetto, in questo modo:
$ symfony new symfony7_rest_api --version="7.1.*"
$ cd symfony7_rest_api
Una volta portate a termine queste semplici operazioni, entriamo nel vivo del tutorial, potrebbe essere necessario installare anche alcuni altri pacchetti come php-mysql, php-xml e unzip prima di procedere, portate a termine questi compiti con lo strumento apt di Ubuntu, coi necessari privilegi.
Dopo aver installato Symfony, ed essere entrati nella sua root directory, digitiamo i seguenti comandi, per installare il modulo ORM e l’utility maker bundle:
$ composer require symfony/orm-pack
$ composer require symfony/maker-bundle --dev
Una volta fatto questo impostiamo la connessione al database, commentando la linea su PostgreSQL, decommentando e modificando in questo modo la linea su MySQL, nel file .env nella root directory del progetto:
DATABASE_URL="mysql://youruser:yourpassword@127.0.0.1:3306/app?serverVersion=8.0.32&charset=utf8mb4"
A questo punto siamo in grado di creare il database e la nostra entità con i seguenti comandi, in questo tutorial creiamo un’entità di nome Article con quattro campi: title, author, body, url:
$ php bin/console doctrine:database:create
$ php bin/console make:entity
Ora invece siamo in grado di creare la tabella nel database, con i seguenti comandi:
$ php bin/console make:migration
$ php bin/console doctrine:migrations:migrate
Dunque creiamo il nostro controller, il quale andrà poi editato, usiamo questo comando per farlo:
$ php bin/console make:controller ArticleController
Adesso andiamo ad editare il controller appena creato, di seguito creeremo le routes per ogni action del controller, in src/Controller/ArticleController.php:
namespace App\Controller;
use App\Repository\ArticleRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
class ArticleController extends AbstractController
{
private $articleRepository;
public function __construct(ArticleRepository $articleRepository)
{
$this->articleRepository = $articleRepository;
}
#[Route('/article', name: 'add_article')]
public function add(Request $request): JsonResponse
{
$title = $request->query->get('title');
$author = $request->query->get('author');
$body = $request->query->get('body');
$url = $request->query->get('url');
if (empty($title) || empty($author) || empty($body)) {
throw new NotFoundHttpException('Expecting mandatory parameters!');
}
$this->articleRepository->saveArticle($title, $author, $body, $url);
return new JsonResponse(['status' => 'Article created!'], Response::HTTP_CREATED);
}
#[Route('/article/{id}', name: 'get_article')]
public function get($id): JsonResponse
{
$article = $this->articleRepository->findOneBy(['id' => $id]);
$data = [
'title' => $article->getTitle(),
'author' => $article->getAuthor(),
'body' => $article->getBody(),
'url' => $article->getUrl()
];
return new JsonResponse($data, Response::HTTP_OK);
}
#[Route('/articles', name: 'get_articles')]
public function getAll(): JsonResponse
{
$articles = $this->articleRepository->findAll();
$data = [];
foreach ($articles as $article) {
$data[] = [
'title' => $article->getTitle(),
'author' => $article->getAuthor(),
'body' => $article->getBody(),
'url' => $article->getUrl()
];
}
return new JsonResponse($data, Response::HTTP_OK);
}
#[Route('/article/{id}/params', name: 'update_articles')]
public function update($id, Request $request): JsonResponse
{
$article = $this->articleRepository->findOneBy(['id' => $id]);
$article->setTitle($request->query->get('title'));
$article->setAuthor($request->query->get('author'));
$article->setBody($request->query->get('body'));
$article->setUrl($request->query->get('url'));
$updatedArticle = $this->articleRepository->updateArticle($article);
return new JsonResponse($updatedArticle->toArray(), Response::HTTP_OK);
}
#[Route('/article/{id}', name: 'delete_article')]
public function delete($id): JsonResponse
{
$article = $this->articleRepository->findOneBy(['id' => $id]);
$this->articleRepository->removeArticle($article);
return new JsonResponse(['status' => 'Article deleted.'], Response::HTTP_NO_CONTENT);
}
}
Ecco invece le routes in config/routes.yaml, possiamo editarle ad esempio con nano:
controllers:
resource:
path: ../src/Controller/
namespace: App\Controller
type: attribute
add_article:
path: /article
controller: App\Controller\ArticleController::add
methods: POST
get_article:
path: /article/{id}
controller: App\Controller\ArticleController::get
methods: GET
get_aricles:
path: /articles
controller: App\Controller\ArticleController::getAll
methods: GET
update_article:
path: /article/{id}/params
controller: App\Controller\ArticleController::update
methods: PUT
delete_article:
path: /article/{id}
controller: App\Controller\ArticleController::delete
methods: DELETE
Ora andiamo ad editare gli ultimi due files, il primo, src/Entity/Article.php:
namespace App\Entity;
use App\Repository\ArticleRepository;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity(repositoryClass: ArticleRepository::class)]
class Article
{
#[ORM\Id]
#[ORM\GeneratedValue]
#[ORM\Column]
private ?int $id = null;
#[ORM\Column(length: 100)]
private ?string $title = null;
#[ORM\Column(length: 100)]
private ?string $author = null;
#[ORM\Column(length: 255)]
private ?string $body = null;
#[ORM\Column(length: 100, nullable: true)]
private ?string $url = null;
public function getId(): ?int
{
return $this->id;
}
public function getTitle(): ?string
{
return $this->title;
}
public function setTitle(string $title): static
{
$this->title = $title;
return $this;
}
public function getAuthor(): ?string
{
return $this->author;
}
public function setAuthor(string $author): static
{
$this->author = $author;
return $this;
}
public function getBody(): ?string
{
return $this->body;
}
public function setBody(string $body): static
{
$this->body = $body;
return $this;
}
public function getUrl(): ?string
{
return $this->url;
}
public function setUrl(?string $url): static
{
$this->url = $url;
return $this;
}
public function toArray()
{
return [
'title' => $this->getTitle(),
'author' => $this->getAuthor(),
'body' => $this->getBody(),
'url' => $this->getUrl()
];
}
}
In questo caso abbiamo semplicemente aggiunto il metodo toArray(), il secondo file da editare è questo, src/Repository/ArticleRepository.php:
namespace App\Repository;
use App\Entity\Article;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Doctrine\ORM\EntityManagerInterface;
/**
* @extends ServiceEntityRepository<Article>
*/
class ArticleRepository extends ServiceEntityRepository
{
private $manager;
public function __construct(ManagerRegistry $registry, EntityManagerInterface $manager)
{
parent::__construct($registry, Article::class);
$this->manager = $manager;
}
public function saveArticle($title, $author, $body, $url)
{
$article = new Article();
$article
->setTitle($title)
->setAuthor($author)
->setBody($body)
->setUrl($url);
$this->manager->persist($article);
$this->manager->flush();
}
public function updateArticle(Article $article): Article
{
$this->manager->persist($article);
$this->manager->flush();
return $article;
}
public function removeArticle(Article $article)
{
$this->manager->remove($article);
$this->manager->flush();
}
}
A questo punto il progetto è completo e funzionante, facciamolo partire con il seguente comando:
$ symfony server:start
Per testare il funzionamento di ciò che abbiamo creato non dobbiamo fare altro che aprire una nuova tab e usare cURL per raggiungere gli end point:
$ curl -X POST "http://127.0.0.1:8000/article?title=Titolo%20Articolo&author=Nome%20Autore&body=Testo%20del%20post&url=Url%20del%20sito"
$ curl -X POST "http://127.0.0.1:8000/article?title=Titolo%20Articolo&author=Nome%20Autore&body=Testo%20del%20post&url=Url%20del%20sito"
$ curl -X GET "http://127.0.0.1:8000/articles"
$ curl -X PUT "http://127.0.0.1:8000/article/1/params?title=Titolo%20Articolo&author=Mirko%20Benedetti&body=Testo%20del%20post&url=Url%20del%20sito"
$ curl -X GET "http://127.0.0.1:8000/article/1"
$ curl -X DELETE "http:/127.0.0.1:8000/article/1"
$ curl -X GET "http://127.0.0.1:8000/articles"
Turorial Completo su Symfony 7 REST API, Conclusioni:
In questo tutorial, ho spiegato come installare Symfony, configurare il database e creare endpoint API efficienti. Il mio obiettivo è fornire una guida pratica di partenza per aiutarti a sviluppare API robuste e scalabili.
Se l’argomento ti interessa e vuoi ampliare la tua conoscenza, sei libero di contattarmi per avere ulteriori dettagli e per discuterne con me, esprimendo le tue idee in merito.
Ti è piaciuto questo post? Commenta qui sotto e condividilo nei tuoi social network preferiti, per farmi udire meglio. Grazie di cuore!