Symfony 7 REST API Tutorial Completo

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.

Mirko Benedetti, Symfony 7 Rest Api Tutorial Completo

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 ArticleController.php nella cartella src/Controller/.

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 l’editor 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, Article.php nella cartella src/Entity/.

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, ArticleRepository.php nella cartella src/Repository/.

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? Leggi tutto l’articolo con i commenti, commenta e condividilo nei tuoi social network preferiti per farmi udire meglio. Grazie di cuore!

Mirko Benedetti, 2024

Mirko Benedetti è l’informatico e copywriter con esperienza pluriennale nel campo dello sviluppo, scrittura web e nelle tecnologie delle telecomunicazioni.

Commenti

2 risposte a “Symfony 7 REST API Tutorial Completo”

  1. Avatar Mirko Benedetti

    Grazie per aver letto il mio articolo su Symfony 7 e REST API! Ho illustrato come installare Symfony, configurare il database e creare endpoint API efficienti e scalabili. Spero che la guida ti sia stata utile per i tuoi progetti. Mi piacerebbe conoscere le tue opinioni e suggerimenti nei commenti!

  2. Avatar Mirko Benedetti
    Mirko Benedetti

    Ciao. In questo articolo ho voluto affrontare la creazione di un semplice oggetto appartenente al framework Symfony e delle componenti necessarie per fare funzionare il suo endpoint REST. La guida offre sia una panoramica sui prerequisiti, che una semplice metodica per verificare in maniera manuale il software appena creato.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *