Tag: Symfony

  • Symfony 7 come REST API, il mio 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!

  • Un’introduzione allo Sviluppo Web e alla Programmazione

    Salve a tutti! Sono Mirko Benedetti, un esperto informatico nonché copywriter, e vi guiderò gradualmente in questo percorso. In questo articolo, “Un’introduzione allo sviluppo web” approfondirò alcune delle tematiche più frequenti nell’ambito dello sviluppo web.

    Una breve, ma Esaustiva Introduzione Storica e Tecnica del Web e di Internet.

    Lo sviluppo web ha avuto il suo apice in italia sul finire degli anni ’90, quando una miriade di utenti non qualificati e non esperti, si è riversata su di esso.

    Mirko Benedetti, Un'introduzione allo Sviluppo Web

    Questo ha creato un mare di informazioni di tipo pluralistico, ma anche intricato e difficilmente verificabile.

    Con gli anni 2000 si è originato un fenomeno che prende mossa dal web e sfocia nello sviluppo mobile. Dunque il focus, si è rivolto verso l’utenza, che è divenuta sempre più esigente e ha cercato contenuti più facilmente e velocemente fruibili.

    Dal web informativo e dopo la bolla ‘dot com’ degli anni successivi, si è passati allo sviluppo delle ‘web app’ con l’introduzione nel mercato di dispositivi sempre più performanti e duttili, gli smartphone.

    A questo punto, è entrata a far parte della vita dell’utente la pubblicità mirata, con la profilazione delle abitudini in rete attraverso i cookies. Questi piccoli elementi di testo vengono memorizzati nel proprio dispositivo e sono poi in grado di essere letti da chi li emette.

    Introduzione allo Sviluppo Web, Le Ultime Novità Tecnologiche.

    Altra ondata di novità è la nascita del web semantico e interattivo. I chatbot sono adesso in grado di acquisire conoscenza in maniera statistica, su enormi basi dati presenti nel web, per poi riversarla in risposta automatica alle domande poste dall’utente.

    Dal punto di vista del programmatore, questo ha visto l’avvicendarsi di tecnologie sempre più complesse che sono andate man mano raffinandosi.

    Si è passati dall’HTML a JavaScript, PHP e Java solo per citarne alcuni; dall’ipertesto ai media tradizionali come il video e l’audio, non tralasciando mondi virtuali creati con la computer grafica, il gioco on-line.

    Oggigiorno la pubblicità e i servizi sono le fonti di monetizzazione maggiore del web. Rimane promettente, ma non affermata, la creazione di valuta virtuale come i bitcoin.

    Si è dunque affermata, oltre al mero sviluppo, la figura dell’usability tester e del marketer. Questi due personaggi lavorano sul rendere il prodotto informatico più rispondente ai bisogni umani. Non dimentichiamo neanche la crociata del diritto online, per la privacy, i diritti d’autore ed altro ancora.

    Si è passati dal programmare al progettare il web, perchè si sono inserite nuove figure non strettamente tecniche nel senso informatico, ma molto più legate alla vita quotidiana, come l’intrattenimento, la ristorazione, la moda o i viaggi.

    Dal sito informativo si è dunque passati al sito interattivo e commerciale, con la creazione di grandi realtà di vendita di beni materiali e distribuzione organizzata su vasta scala, come la società fondata da Jeff Bezos.

    Introduzione allo Sviluppo Web, la Figura dello Sviluppatore.

    Il programmatore non è più quindi una figura necessariamente ‘core business’ in tutti gli ambiti informatici, anche perchè si sono affermate professionalità complementari e trasversali.

    Con l’avvento della pandemia del 2019, si è sempre più affermato il lavoro domestico anche per chi esegue mansioni informatiche, con tutte le sue complicanze relazionali.

    D’altro canto, si è verificato un fenomeno che aveva preso piede già negli anni precedenti alla pandemia, ovvero la creazione di gruppi sociali e siti dedicati a questo scopo come il social network creato da Mark Zuckerberg.

    Non cito altri protagonisti, come gli inventori dei sistemi operativi o dei motori di ricerca. Questo non perchè non abbiano avuto importanza nello sviluppo web, ma perchè ne stanno semplicemente alla base. Li citerò in articoli più pertinenti, se questo dovesse risultarmi sufficientemente esemplificativo.

    L’ultima frontiera dello sviluppo web attiene alla politica e la salute, la pubblica amministrazione.

    Anche in questi settori come lo era negli altri, è utile attuare un approccio integrato che porta ad un prodotto performante, grazie ai tecnici, ma anche convincente, grazie ai marketer.

    Il prodotto deve essere soprattutto utile, grazie ad un approccio integrato tra online e offline. Questo lo si realizza attraverso un processo che va al di là della progettazione, ma che comprende anche la strategia.

    Un’introduzione allo Sviluppo Web, Collegamenti per Approfondire.

    Se vi ho convinto a diventare sviluppatori web e vi ho orientato, ecco alcune tecnologie che vi consiglio per iniziare:

    Ecco un Esempio di Codice Scritto per Symfony.

    // src/Controller/NumeroFortunatoController.php
    
    namespace App\Controller;
    use Symfony\Component\HttpFoundation\Response;
    
    class NumeroFortunatoController
    {
        public function numero(): Response
        {
            $numero = random_int(0, 100);
            return new Response(
                '<html><body>Numero Fortunato: '.$numero.'</body></html>'
            );
        }
    }

    La prima riga di codice è un commento, introdotto dalla doppia barra, un commento su singola linea, si possono creare anche commenti su più linee.

    Il commento serve al programmatore per avere una nota mnemonica, in questo caso ci ricorda che il nostro programma è scritto su un file che sta nella directory ‘src/Controller’ del progetto Symfony.

    Il nome del file ha estensione ‘php’, la quale rappresenta il linguaggio di programmazione usato da Symfony. Questo nome deve corrispondere al nome della classe, la classe è il mattone fondamentale sul quale si fonda il framework, perchè è basato sugli oggetti.

    Un’introduzione allo Sviluppo Web: La Programmazione ad Oggetti.

    La programmazione ad oggetti realizza l’astrazione fra l’implementazione vera e propria e il concetto che vogliamo tradurre in codice.

    All’interno della nostra classe viene utilizzato un namespace, il quale non è altro che una suddivisione per aree semantiche o di scopo delle classi del programma.

    In questo caso lo scopo della classe è quella di fare da controller, quindi gli si da un nome che termina per ‘controller’.

    Il controller è la parte fondamentale del framework, ovvero quella che decide cosa fare in base all’indirizzo ‘url’ chiamato dall’utente.

    In questo caso, il controller vuole restituire un messaggio con un numero casuale. Per fare questo, esso utilizza la classe di Symfony ‘Response’, introdotta dal costrutto ‘use’.

    La nostra classe, introdotta dal costrutto ‘class’, ha un metodo che abbiamo chiamato ‘numero’, in modo da esemplificare meglio.

    Un’introduzione allo Sviluppo Web, i Nomi nella Programmazione.

    Si consiglia però di utilizzare nomi inglesi ‘parlanti’, che spieghino cioè di che cosa trattano. I nostri nomi dovrebbero comunque essere dissimili da quelli usati dal framework o dal linguaggio in questione. Questo per non creare confusione tra ciò che abbiamo scritto noi e ciò che è già presente in essi. La cosa migliore poi è essere uniformi.

    Il metodo ‘numero’ è una funzione della classe, ovvero una porzione di codice che esegue un comando ben specificato. Il metodo ha una sua variabile interna chiamata ‘$numero’.

    Questa variabile viene passata ad un oggetto che viene istanziato attraverso il costrutto ‘new’, questo oggetto viene restituito dal metodo attraverso il costrutto ‘return’.

    Il tipo di questo oggetto, ovvero la classe da cui è istanziato, è ‘Response’ e viene indicato nella firma del metodo, dopo i due punti nella sua dichiarazione. Il metodo è dichiarato come pubblico col costrutto ‘public’, ovvero può essere richiamato dall’esterno della classe.

    La differenza tra classe e oggetto sta nel fatto che la classe ne è il suo prototipo, mentre l’oggetto assume dei valori specifici in memoria, detti stato. Entrambi hanno la possibilità di andare in esecuzione.

    Altra cosa da capire è il parametro passato al costruttore del nuovo oggetto di tipo ‘Response’. Si tratta di codice HTML in cui viene interpolata la variabile ‘$numero’.

    Il costruttore è una funzione che istanzia un oggetto a partire da un tipo, ovvero da una classe.

    In ultimo sottolineo il concetto di ereditarietà e polimorfismo nella programmazione ad oggetti, dove alcune classi ereditano gli stessi attributi da classi genitori, avendo la possibilità di introdurre delle modifiche.

    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!