Torna a tutti gli episodi
Ep.8 - Orm: Datamapper and Active records. Programmazione della persistenza!

Episodio 8

Ep.8 - Orm: Datamapper and Active records. Programmazione della persistenza!

Ogni applicazione che noi realizziamo ha bisogno di tenere conto della persistenza, abbiamo iniziato la nostra esperienza con la programmazioneinserendo delle query in "RAW SQL" nel nostro codice sorgente ma presto ci siamo resi conto che mischiare i linguaggi, nel mio caso php e sql, non era una co...

20 febbraio 202000:31:53
AIMusic
8

In Riproduzione

Ep.8 - Orm: Datamapper and Active records. Programmazione della persistenza!

0:000:00

Note dell'Episodio

Ogni applicazione che noi realizziamo ha bisogno di tenere conto della persistenza, abbiamo iniziato la nostra esperienza con la programmazioneinserendo delle query in "RAW SQL" nel nostro codice sorgente ma presto ci siamo resi conto che mischiare i linguaggi, nel mio caso php e sql, non era una cosa buona e giusta quindi abbiamo attinto dal mondo dei pattern e di siamo trovati davanti agli ORM, object relation mapper confondendoci alla vista di active records e data mapper.Esiste un modo migliore degli altri per effettuare il salvataggio dei nostri dati, se si in che contesto. Questa puntata è un piccolo viaggio con delle sorprese.#Capitoli0:00 Saluti iniziali4:31 I pattern di programmazione5:35 La persistenza8:26 Gli ORM 13:29 Active Record20:25 Data Mapper25:54 Quale è il miglior approccio29:37 Saluti finali#Contatti@brainrepo su twitter o via mail a info@gitbar.it#CreditiLe sigle sono state prodotte da MondoComputazionaleRegistrato negli studi di Radio Nuoro CentraleLe musiche da Blan Kytt - RSPN

Descrizione

Dopo un mese e mezzo di podcast, abbiamo annunciato l'arrivo delle dirette Twitch di live coding per costruire il nuovo sito di GitBar con Jigsaw (generatore di siti statici in PHP). Ma prima, ci siamo tuffati nei pattern ORM parlando di Active Record vs Data Mapper: il primo è come avere un ponte invisibile tra database e oggetti (facile e veloce ma accoppiato), il secondo è come avere un layer intermedio che ti libera dal database (verboso ma Domain-Driven Design friendly). Laravel vs Symfony? Eloquent vs Doctrine? Tutto dipende dal bullone che hai davanti.

Takeaway

  • L'Active Record accoppia oggetti e schema database 1:1: leggi il database e capisci l'app, ma testare diventa complesso perché ogni oggetto interagisce sempre con il DB
  • Il Data Mapper (Doctrine) separa dominio e persistenza con file di configurazione (XML/YAML) o annotation: le entità hanno una sola responsabilità (business logic), non persistenza
  • Laravel (Eloquent/Active Record) è RAD per prototipi rapidi, Symfony (Doctrine/Data Mapper) è enterprise per situazioni complesse con database legacy contorti
  • Il pattern Active Record non ha il concetto di Unit of Work come Doctrine, quindi genera più query e le performance calano all'aumentare della complessità
  • Usare ORM riduce il boilerplate SQL e permette validazione applicativa, ma può generare più query del raw SQL necessario (trade-off tra velocità di sviluppo e ottimizzazione)

Bold Opinion

  • Scrivere raw SQL nel mezzo del PHP come all'università è un crimine contro l'umanità: mischiare linguaggi richiede sforzo mentale inutile
  • Il vantaggio dell'Active Record (generare oggetti dallo schema DB automaticamente) è anche il suo limite più grande quando erediti database scritti male con nomi di colonne orribili
  • Non esiste il "meglio assoluto" in informatica: chi ti vende questa idea ti sta vendendo fesserie, tutto dipende dal contesto
  • Il Data Mapper è più verboso ma il rischio di scadere nel modello anemico (solo getter/setter, logica tutta nel controller) è reale se non stai attento

Trascrizione

Benvenuti su GITBAR il podcast dedicato al mondo dei full stack developer, i mezzo artigiani, mezzo artisti che ogni giorno infilano le mani nel fango per creare nel modo più efficace possibile quei prodotti digitali che quotidianamente utilizziamo.Eccoci qua, ottava puntata di GITBAR.Io sono BrenRap e anche oggi vi accompagno in uno di quelli che sono gli argomenti del mondo dei full stack developer ma prima di farlo voglio darvi un'anticipazione ormai è passato un mese e mezzo da quando son partito con questo podcast e quindi sento già l'esigenza di proporvi qualcosa di nuovo qualcosa di fresco e qualcosa di diverso per cui sto ragionando sulla possibilità di fare delle dirette twitch.Dirette che sono delle sessioni di live coding dove aprirò php storm e inizierò a fare qualcosa.Io spero possano piacervi.Cosa andrò a fare in queste dirette? Nella prima sessione di live coding mi piacerebbe iniziare con voi a lavorare sul nuovo sito di Gitbar.Ho già qualche idea in realtà sia sulla funzionalità che su come deve essere esteticamente.Per cui aprirò appunto l'editor e inizierò a scrivere.Quali sono le tecnologie che andremo a usare per questo sito? Beh mi interessa fare un sito statico.Vi sembrerà strano sentirmi parlare in questo modo ma fondamentalmente il fondamentalmente il sito per il podcast non ha bisogno di avere un back end, essere configurabile ma semplicemente basta che mostri gli episodi con le note, la possibilità di ascoltarli, la possibilità di iscriversi al podcast e i contenuti aggiuntivi quindi sono semplicemente dei calderoni dei contenitori di contenuti, scusate la cacofonia, per farlo ho pensato di utilizzare jigsaw.Jigsaw che cos'è? Jigsaw è un software in php che permette la generazione di pagine statiche, contemplate e quant'altro a partire da una serie di documenti che possono essere markdown e quindi va a generare il nostro sito che poi andremo ad uploadare.Ancora non ho deciso se la uploaderò nello super chip che ho comprato top post che penso sia più che sufficiente oppure se uploadarlo direttamente su un bucket s3 di amazon e di lì poi diciamo aggiornarlo sempre.A corredo della realizzazione del sito è mia intenzione andare a fare una serie di sessioni di coding dove vado a realizzare uno strumento che mi sarà molto utile poi per la gestione del podcast per esempio uno strumento che mi permetta di fare lanciando un solo comando il transcript della puntata.Cosa che per poterlo fare oggi devo aprire amazon entrare nei servizi AWS andare nell'area transcript e avviare la trascrizione invece se potessi farlo direttamente da command line e automatizzare magari l'azione nel momento in cui io metto un mp3 nella mia cartella podcast con un certo formato e ezel chiama questo servizio o automator chiamano questo servizio questo potrebbe essere molto interessante ecco questa è la direzione che voglio prendere a corredo di quello che è il podcast quindi esplorerò probabilmente anche un po' il mondo SEO che non conosco perché io sono un sviluppatore non un esperto in indicizzazione però lo faremo insieme sarà un'esperienza che condividerò con voi.Sono ormai passati quattro minuti di anticipazione e dobbiamo andare ai contenuti.Oggi parliamo di pattern di programmazione e parliamo dei pattern ORM.Intanto una premessa va fatta, penso li conosciate, ma comunque voglio farla per in qualche modo introdurre il concetto di pattern.In informatica quello che noi andiamo a fare con la programmazione è quella di creare delle soluzioni a dei problemi.I problemi alle volte possono essere ricorrenti per cui ricorrenti o assimilabili per cui utilizzare una soluzione che è fitta con quel problema diciamo ci aiuta per cui è possibile utilizzare una soluzione che abbiamo individuato precedentemente per un problema simile al nostro nuovo problema per cui il pattern è una soluzione comune a un problema ricorrente, possibilmente anche ottimizzata.Diciamo che la best practice delle soluzioni ha un problema ricorrente.Bene, qual è allora il problema ricorrente che andremo ad analizzare oggi? Beh, parliamo della persistenza.Tutte le nostre, o buona parte delle nostre applicazioni, devono in qualche modo avere una memoria, quindi devono salvare i dati.Il salvataggio di questi dati solitamente lo si fa all'interno di database o di basi di dati.Questo permette che qualunque cosa succeda al nostro sistema in qualche modo i nostri dati, qualora si spengano i server, i nostri dati sono sempre raggiungibili.Diciamo che la persistenza può essere fatta con tecnologie differenti a partire dal classico database MySQL o Postgre nell'ecosistema LAMP ha già sistemi più complessi come MongoDB e Cassandra che sono dei SQL o ha un GraphDB o ha un Redis insomma la persistenza può utilizzare tecnologie diverse.Ma torniamo per un secondo alla persistenza con i database relazionali.Quindi parliamo di Postgre, parliamo di MySQL In qualche modo l'azione di persistere all'interno del database fa parte dell'insieme delle azioni legate alla piattaforma che stanno nel nostro codice quindi tutte le funzioni che vanno a interagire sulla piattaforma.Cosa vanno a fare queste funzioni? Beh queste funzioni non fanno altro che prendere gli oggetti del nostro software e trasformarli in record che sono invece un concetto molto più vicino al database stesso e poi a sua volta vanno a prendere i record figli di query e li vanno a trasformare in oggetti del nostro sistema.Mi verrebbe da dire in oggetti del dominio qualora appunto programmasimo utilizzando appunto l'approccio ddd e domain drive and design però comunque in oggetti che sono legati al nostro software.Quando ero all'università un po' di anni fa, iniziano essere un bel po', spesso incappavo in codice dove in mezzo al codice c'erano le query SQL quindi raw SQL in mezzo al PHP per esempio visto che era quello il linguaggio che io trattavo.Bene, mettere il linguaggio SQL in mezzo al PHP capite bene che non è la scelta migliore e quindi si aveva la necessità e si ha la necessità di utilizzare degli object relation mapper chiamati anche ORM che si occupano appunto come vi dicevo prima di trasformare gli oggetti in record e i record in oggetti nel nostro software.Il compito infatti dell'ORM è quello di gestire, lato nostro applicativo, tutti i processi per la persistenza nella memoria fisica.Quali sono i vantaggi che abbiamo nell'utilizzo di un ORM? Beh, intanto non mettiamo le sequelle in mezzo al nostro codice.Mischiare i linguaggi non è mai una cosa buona, perché comunque serve un certo sforzo mentale per passare da un linguaggio all'altro mentre stiamo leggendo il nostro codice B perché comunque potrebbero le query SQL potrebbero dover essere gestite da un'altra persona e quindi tutto insieme diventa caotico.Altro vantaggio che ci permettono gli ORM è quello della validazione.Possiamo infatti inserire un livello di validazione, una lista di constraint nel nostro codice senza demandare la validazione direttamente al database.Questo è un vantaggio perché in realtà possiamo gestire meglio gli errori di validazione invece quando una query fallisce sapete bene che la risposta è sempre legata alla query stessa non all'azione che si sta andando a fare.Un altro vantaggio importante è quello di ridurre il codice boilerplate infatti le SQL di per sé come linguaggio è molto verboso quindi per fare una query dobbiamo scrivere parecchio ecco gli ORM mettono a disposizione dei query builder che diciamo ci aiutano nella scrittura di una query e un'altra cosa importante è appunto quella che vi dicevo prima dell'ordine infatti possiamo facilmente dividere in questo modo le query SQL dal nostro dominio.Naturalmente come tutte le cose come vi dico sempre spesso le soluzioni più belle hanno comunque dei limiti dei difetti.Beh uno di questi limiti è appunto il fatto che l'ORM produce più query per eseguire appunto un certo blocco di codice potrebbe generare più query di quelle che in realtà potrebbero essere necessarie nella scrittura del codice SQL raw.Però è vero anche che dei tool moderni come Doctrine introducono dei concetti come per esempio la unit of work che poi andremo a vedere che in qualche modo ottimizza e rende più performante il nostro codice eseguendo in una sola transazione appunto le nostre più query.Certo rimane comunque inefficiente perché perché l'ottimizzazione il tuning che possiamo fare quando agiamo direttamente nelle query non è lo stesso che possiamo fare usando lo RM.Anche questo è parzialmente vero nel senso che Doctrine mette a disposizione il linguaggio DQL che non è altro che una sorta di astrazione di livello superiore del linguaggio SQL abbiamo meno controllo questo è ovvio e quindi tutto ci sembra più magico e soprattutto il problema vero è un altro il problema è che quando noi scriviamo il codice SQL nella nostra applicazione per forza siamo spinti a pensare un minimo all'ottimizzazione quindi siamo spinti scrivendo il codice SQL a dire sì va beh ma forse questa join la faccio in quest'altro modo non la faccio in quest'altro modo ma quando noi utilizziamo questi tool siamo in qualche modo invogliati a concentrarci di più sul dominio applicativo quindi su quelle che sono le vere funzioni pratiche che il nostro software va ad eseguire per cui in qualche modo scriviamo del codice senza avere l'ottimizzazione in testa e quindi diventa meno performante.Fatta questa introduzione però è capito cosa sono gli object relation mapper vorrei introdurvi le due implementazioni più importanti più famose del ORM.La prima è l'active record, la seconda invece è il data mapper.Il primo pattern che andremo a vedere è il pattern active record che tradotto letteralmente vuol dire record attivi quindi record con una serie di azioni.Sono degli oggetti, sono degli oggetti le cui proprietà in un modo o nell'altro vanno a mappare le colonne e si occupano del appunto trasporto tra dei dati dalla nostra applicazione al database.Possiamo quasi immaginarlo come un ponte invisibile.Cosa possono fare questi ActiveRecord? Beh, gli ActiveRecord hanno funzionalità diverse intanto tengono i dati quindi un oggetto detiene archivia in qualche modo prende in uso i dati di un record specifico oltre a questo però si occupano delle azioni di persistenza quindi implementano il metodo save e si occupano anche di andare a ottenere di fare il retry di record dalla tabella di un insieme di record alla tabella quindi sono anche delle collection delle collezioni di dati la cosa è un po strane in realtà e suono un pochino male pensare che in realtà un oggetto possa essere elemento di una collection ma ti permetta anche di avere indietro una collection stessa però diciamo questa è la funzionalità dell'active record che per sua natura è molto semplice da realizzare ma ha dei limiti.Intanto andiamo a vedere i vantaggi senza dubbio i record sono accoppiati con gli oggetti quindi la nostra struttura del database la ritroviamo pediseguamente all'interno dell'oggetto che andremo a maneggiare nel nostro codice questo è un vantaggio perché in realtà in un solo colpo io conosco due sistemi e non mi vado a incasinare e quindi quando leggo il database capisco direttamente la struttura dell'applicazione senza dover stare là a leggere dei livelli intermedi che mi vanno a trasformare gli oggetti di dominio in schema di database.Un altro vantaggio sempre legato a questa relazione forte con lo schema del database è il fatto che in un solo colpo con degli algoritmi non troppo complessi io posso generare degli oggetti dallo schema stesso e diciamo che è funzionale quando si ha bisogno di un approccio facile e veloce perché in realtà interagire con oggetti che implementano il pattern active record ci permette per esempio di non inizializzare tutte le proprietà nel nostro oggetto per fare il collegamento con le colonne insomma ci taglia tutta una serie di livelli di complessità che in un'applicazione enterprise sono molto utili ma nello sviluppo di un MVP neanche troppo complesso beh potrebbero essere overkilled.In realtà i vantaggi dell'Active Record sono anche i suoi limiti.Uno dei suoi limiti è appunto questo accoppiamento db oggetto software.Infatti è difficile utilizzare oggetti senza andare a interagire col db.Faccio un esempio, io implemento la mia logica di dominio nella mia applicazione.Prendiamo l'oggetto carrello.Ok, questo oggetto carrello essendo implementato con il pattern active record va a interagire con il database.Ma se io volessi utilizzare il crea ordine per esempio o interagire con l'ordine senza dover necessariamente interagire col database potrei avere dei problemi e tra l'altro un altro limite importante è quello di testarli questi oggetti perché perché in realtà avendo un legame così stretto con l'architettura col livello di infrastruttura fare un test unitario diventa più complesso non dico che sia impossibile perché comunque è possibile testarli però per esempio se tu vai a testare un modello Eloquent diciamo che puoi testare i metodi che alcuni metodi non tutto anche perché magicamente appaiono per esempio delle proprietà che sono quelle che si vanno a generare automaticamente nel momento in cui io collego il modello di Eloquent che è l'ORM di Laravel al database Un altro limite lo troviamo quando andiamo a sviluppare la nostra app su dei database che esistono già.Quando sviluppiamo la nostra app su database che esistono già, impattiamo con un limite che è quello che il database potrebbero essere scritto male, diciamo i nomi delle colonne potrebbero non essere migliori, oppure la struttura stessa dei database, delle tabelle non rispecchia pedosequamente quella che è la struttura concettuale di dominio.Per cui usando diciamo il pattern active record mi trovo davanti al problema che gli oggetti che poi mi porterò appreso in tutto lo sviluppo della logica di business della nostra applicazione avranno lo stesso schema di una tabella del database che non ho sviluppato io, che magari non mi piace o non fa quello che deve fare e quindi insomma potrebbe essere un limite anzi lo è sicuramente quando noi andiamo a fare delle web app complesse e poi un altro limite del pattern active record è senza dubbio il fatto che all'aumentare della complessità del numero dei record le performance vanno a diminuire questo perché in realtà perlomeno io parlo di eloquent che è quello che conosco meglio non è previsto il concetto così come c'è su doctrine che invece implementa un altro pattern che è quello del data mapper che andremo a vedere dopo che è quello del unit of work che anche questo concetto insomma lo andremo a vedere con più calma dopo per cui diciamo che il vantaggio di un approccio con l'active record è quello di avere degli oggetti facili, facilmente gestibili, degli oggetti che rispecchiano la stessa struttura del database quindi leggendo il database ho presto capito come è strutturata la mia applicazione e diciamo un approccio abbastanza facile.Di contro ci sono tutte appunto i limiti che abbiamo detto prima.Il secondo pattern che andiamo a vedere si chiama data mapper per capirci è quello utilizzato da doctrine l'ORM di symphony parlo di php perché il mondo che più mi sta vicino e che ha il compito di creare un layer un livello intermedio tra il dominio della nostra applicazione e il db.Infatti dominio e db risultano essere indipendenti.Questa indipendenza ci permette per esempio di sviluppare un approccio domain drive and design dove io mi concentro semplicemente sulle entità del mio dominio e poi queste entità in qualche modo vanno a essere persistite all'interno del nostro sistema.Con l'approccio di data mapper spesso le proprietà sono private a differenza appunto dell'active record e la scrittura e la lettura di queste proprietà avviene attraverso dei metodi accessori che appunto espongono queste proprietà però per accedere a queste proprietà devi passare attraverso di loro.Questo ci permette per esempio di validare delle constraint al posto di andare a scrivere direttamente.Questi sistemi collegano in qualche modo la nostra logica di dominio col database e lo fanno attraverso modi diversi.Lo fanno attraverso per esempio dei file di configurazione in xml o in yml, yaml o lo fanno attraverso i commenti perché no doctrine per esempio quando si vuole sviluppare in modo molto rapido basta inserire delle annotazioni si chiama la notation sopra le proprietà per decidere cosa mappare e come farlo.Questo livello ulteriore fa da bridge, fa da ponte tra il dominio quindi tutto ciò che riguarda le constraints tutte le azioni che vado a fare sulle proprietà che sono strettamente legati alla nostra logica di dominio, alla persistenza, alla mera persistenza stessa.Questo ci permette in realtà una cosa molto semplice che è una cosa non contemplata nell'active record pattern che è il concetto di singola responsabilità, single responsibility.Infatti la nostra entity ha un'unica responsabilità, quella di gestire le constraint, le regole di business che la riguardano.Tutto il resto, la persistenza, la ricerca, è demandato ad altri elementi del sistema.Non se ne occupa lei.Per cui avendo una distinzione così netta, così semplice, quando ho un problema so che l'oggetto Entity contiene quella porzione di azione, quella porzione di codice e non dovrò impazzire andando a cercare ma quella funzione, quell'azione dove si trovava.Altro vantaggio vero è che le nostre entità sono slegate dallo schema del database perché appunto le mappo usando delle configurazioni XML, YAML, dei commenti, per cui essendo slegate io posso agire con dei concetti che sono più vicini al mio dominio e meno vicini alla mia infrastruttura.Posso usare dei value object, posso utilizzare il polimorfismo.Quindi quando io vado a sviluppare questo covice diciamo che il livello database, il livello infrastruttura mi è comunque invisibile.Naturalmente anche il data mapper pattern ha dei limiti.intanto è più verboso perché in un'entità io devo definire proprietà e metodi accessori, metodi getter e setter questo fa sì che insomma debba scrivere più codice.Occhio che è facile scadere nel concetto del modello anemico che poi vedremo in un altro episodio per cui modello per cui diciamo che facciamo delle entità dove abbiamo solo dei metodi getter e setter che vanno a impostare delle proprietà e non fanno nient'altro e tutto il resto delle constrain le buttiamo nel nostro controller tenendo un modello anemico e un controller grasso ma questo poi sarà parte di un altro episodio per cui ci andremo a concentrare solo su quello.Un altro limite del data mapper è senza dubbio il fatto che diventa spaventoso da configurare e symphony quando vai a configurare il modello e magari lo fai su xml perché vuoi tenere tutto perfettamente disaccoppiato ne è una dimostrazione ed è più difficile esportare quella configurazione in modo automatico.Adesso la domanda sorge spontanea.Qual è il miglior approccio che posso utilizzare? Il primo ragionamento da fare è cosa devi fare? Cioè non esiste un approccio migliore, non esiste decidere perché il meglio assoluto è questo.In informatica chiunque vi propugni l'idea, il concetto del meglio assoluto vi sta dicendo una fesseria grande quanto è il mondo perché in realtà tutto dipende dal contesto e dall'infrastruttura che state andando a gestire.Se avete un'applicazione semplice, un prototipo che deve essere semplice, facile da sviluppare, veloce soprattutto, lo andate a fare col pattern active record.Se invece vi trovate in un contesto tale per cui l'app che dovete fare magari di livello enterprise è complessa o magari eredita uno schema di persistenza, uno schema di database, legacy e magari anche difficile contorto, complesso con tabelle, relazioni contro relazioni, dati divisi in due o tre tabelle, beh a quel punto il mio consiglio più spassionato è quello di utilizzare il data mapper.Data mapper che vi mette a disposizione tutti gli strumenti per semplificare quel contesto difficile.Questo approccio se ci pensate un attimo ce lo riportiamo anche sui framework.Voglio fermarmi un attimo e ragionare su questa cosa.Prendiamo due dei framework più famosi di PHP, uno è l'Aravel e uno è Symfony.premesso che condividono una larga parte del codice visto che l'Aravel si basa e attinge a piene mani da quelli che sono i symphony components, i mattoni che vanno a creare anche i symphony, in realtà l'approccio è completamente diverso.L'Aravel è pensato per applicazioni semplici, rapide da sviluppare, ha un approccio RAD, Rapid Application Development, dove meno codice scrivi e più rapidamente lo fai prima riesci a ottenere il prototipo.Symfony invece utilizza un approccio un pochino più strutturato infatti se noi andiamo a vedere le app enterprise che meglio conosciamo sono in php molte di queste sono fatte con Symfony questo perché in realtà ti mette a disposizione tutta una serie di strumenti che all'inizio presuppongono un affront di complessità, una curva ripida in termini di effort, di sforzo, ma poi ti permettono di gestire situazioni complesse.Ci sono meno magie, meno metodi, cose che accadono e non lo riesci a vedere dal codice e questo si riporta appunto anche nei pattern di persistenza.Se noi andiamo a vedere quello che è il pattern che viene usato dall'Aravel quindi Eloquent vediamo che è un pattern active record se noi andiamo a vedere invece il pattern utilizzato da Symfony vediamo che utilizza Doctrine 2 che è un document mapper quindi in realtà vedete che non esiste uno strumento migliore ma esistono approcci diversi.Quindi da questo punto di vista io ribadisco quello che vi ho detto prima.Scegliete la chiave inglese che volete utilizzare a seconda del bullone che avete davanti.Anche questa puntata è appena terminata e registrata anche questa in macchina perché non sono ancora trattato a Lione ma sto usando un tool nuovo ferrite e spero sia migliore ecco spero tanto è più pratico e questo è un vantaggio e poi spero che l'audio che sto producendo possa essere in qualche modo fruibile.Vi ricordo che questa settimana spero di iniziare al più tardi la prossima spero di iniziare con le dirette twitch vedrò se fare qualcosa o collegarlo anche con youtube però nel frattempo vi chiedo una cosa se la mia puntata vi è piaciuta e in qualche modo volete entrare in contatto con me potete farlo con twitter scrivendomi @brenreppo sto valutando l'idea in realtà di passarvi il contatto telegramma e fare un gruppo telegramma però è solo un'idea non ho ancora deciso cosa fare per cui potete entrare in contatto con me su twitter dirmi se qualcosa vi è piaciuto oppure dirmi se ho detto qualche fesseria in quel caso sono pronto a fare un follow up nella prossima puntata e nulla e come vi dicevo se vi fa piacere ecco aprite la vostra app preferita di podcast che sia google podcast o che sia un podcast di apple, castamatic, pocketcast ce ne sono 70.000 cercate github e iscrivetevi.Dalla Sardegna e soprattutto vi condividerò la foto, sono davanti alla spiaggia perché sto registrando in macchina.È tutto, un saluto e ci vediamo in streaming questa settimana e con la prossima puntata la settimana prossima.Ciao! GitBar, il circolo dei fullstack developer.Una volta a settimana ci troviamo davanti a due birre e con BrainRepo parliamo di linguaggi e tecniche di sviluppo web, di metodologie e di strumenti immancabili nella cassetta degli attrezzi dei fullstack dev.[Musica] [Sottotitoli e revisione a cura di QTSS]