Home Blog

Storia di un Side Project – 5 – Tempi, ritmi e stacchi

1

In termini di gestione del tempo, purtroppo, non posso aiutarvi con dei numeri precisi: nonostante tutti i buoni propositi, infatti, non ho mai tracciato le ore impiegate a lavorare sul progetto.

Posso dire però con certezza che, nell’arco di quasi due anni di vita del progetto, non penso di averci speso, in totale, più di due mesi lavorativi (320 ore).

Ad ogni modo, posso “classificare” il tempo speso in due categorie ben distinte:

Storia di un Side Project – 4 – Evoluzione e Strutture

1

In questa sezione proverò a raccogliere qualche pensiero su tutte quelle cose che ho imparato sull’evoluzione del progetto nel tempo.

Automatizzate. Tutto.

Non smettete mai di misurare tutto quello che è possibile misurare nel vostro side project. Soprattutto quando le cose iniziano a farsi più serie capirete quanto il tempo sia denaro.

Storia di un Side Project – 3 – $weet Dream$

2

Arriviamo al succo della questione. Se avviate un side project che:

  • non fate per beneficenza;
  • non è open-source;
  • magari è un Saas;

prima o poi vorrete vedere anche un po’ di $oldi. Sì ma… come fare? Ovviamente non ho una formula magica, però posso raccontarvi come ho fatto io con la mia app.

Storia di un Side Project – 2 – “Un bullone sì ed uno no, non devi farmi bello”

2

Qualcuno ha riconosciuto la citazione? Siamo in Iron Man, il film del 2008 con Robert Downey Jr. Una di quelle citazioni che per qualche motivo ti rimane impressa e, un bel giorno, ti torna utile.

La frase infatti viene usata quando, per scappare dai terroristi che lo tengono prigioniero, Tony Stark sta finendo di preparare la prima versione dell’armatura che lo renderà un eroe.

Storia di un Side Project – 1 – Segui le briciole

2

Ho sempre pensato di essere molto fortunato nell’amare il lavoro che faccio. Non giriamoci intorno: saper fare bene lo sviluppatore nel 2021 è una bomba. A patto di rimanere aggiornati e sufficientemente curiosi, le possibilità sono tante, stimolanti e discretamente remunerative.

Nel tempo ho conosciuto due categorie di sviluppatori: quelli che amano lo sviluppo in quanto tale e quelli che lo amano in quanto mezzo. Io sono nel secondo gruppo: per me lo sviluppo software è uno strumento potentissimo con cui fare altre cose, risolvere problemi, divertirmi ad automatizzare qualcosa di noioso.

Storia di un Side Project – 0 – Motivazione

1

No tranquilli, non partirò con un pippotto motivazionale. In realtà, voglio spendere qualche parola sul mio modo di vedere la vita ed il lavoro.

C’è una frase di Al Pacino che amo e riassume perfettamente la filosofia che più mi appartiene:

“Forget the career, do the work. If you feel what you are doing is on line and you’re going someplace and you have a vision and you stay with it, eventually things will happen.”

Poco prima delle ferie, mi sono trovato in 1:1 con il mio team leader in Hootsuite. Periodicamente, svolgiamo delle attività di confronto il cui obiettivo è capire se, come dipendenti, ci sentiamo “sulla strada giusta“. Queste call, per me, sono sempre un’occasione per fare un po’ il riassunto delle “puntate precedenti”.

Quando ha chiesto delle mie ambizioni, ammetto di aver avuto qualche difficoltà a rispondere in modo convenzionale. Non ho delle vere e proprie ambizioni: mi riesce da sempre difficile vedere la felicità e la realizzazione come una destinazione.

Storia di un Side Project (e dei suoi primi 1500€/mese)

6

Oggi voglio parlare di un tema che mi è sempre stato molto a cuore: i side project.

Se sviluppate software per vivere, come faccio io, sicuramente ci avete fatto almeno un pensiero (almeno una volta). Non è solo questione di soldi in quanto tali: mi ha sempre attratto molto quell’idea (anche un po’ romantica, se vogliamo) di tirare su qualcosa che può essere utile ad altre persone in giro per il mondo. Magari sviluppata nel tempo libero, con la musica giusta in sottofondo, durante un weekend piovoso.

Qualcosa che a un certo punto diventa abbastanza utile e di valore che c’è chi è disposto a pagare per usarlo, questo qualcosa.

A me è successo: la mia prima app Shopify, Ahia! – Easy Price Changer è arrivata a quasi 150 clienti paganti in giro per il mondo. Piano piano continua a crescere, e prendersi la sua fetta di mercato nel piccolo (grande) mondo di Shopify.

La mia prima applicazione con Laravel Jetstream e Livewire, in 48 ore. Ecco com’è andata

0

L’articolo di oggi inizia con un problema: mi sono scordato di pagare un dominio. Sforo di poche ore, niente di pazzesco, e recupero tutto immediatamente. Il mancato pagamento in tempo, però, crea un po’ di casino nei DNS e, per un paio di giorni, il sito non è raggiungibile. Odio questi contrattempi.

Ora, per vari motivi mi capita di comprare un bel po’ di domini ogni anno. Il mio provider, nel mandarmi i reminder, fa un bel mischione e sempre più spesso i domini più importanti spariscono in mezzo ad altri cinque/dieci alla volta.

Come ogni dev che si rispetti, mi sono detto: “perché non scrivermi da zero un piccolo software che mi ricorda dell’imminente scadenza?”

Essendo appassionato di prodotto, secondo voi, potevo mai scrivermi un semplice tool da linea di comando? Certo che no. Così è nato domain-check.it.

E da qui la sfida che mi sono proposto: creare un piccolo Saas ed usare Laravel Jetstream insieme a Livewire, di cui ho parlato qualche tempo fa con l’ottimo AlessandroEssendo un progetto piccolo ed avendo altre incombenze, mi sono messo una scadenza molto precisa: Domenica 2 Maggio 2021. Praticamente due giorni, considerando che sono partito Venerdì 30 Aprile, sul tardi (6 di pomeriggio).

In questo post racconterò com’è andata.

Le Premesse

La chiacchierata con Alessandro mi aveva intrigato non poco. Chi mi conosce sa bene quanto amo fare prodotto, sperimentare, lanciare un progetto e capire se risolve un problema. Da fuori (non l’avevo mai provato prima) avevo fatto qualche ipotesi su Livewire e Jetstream:

  • vanno bene per i progetti piccoli / mvp;
  • per progetti più grandi, il “mischione” di codice può diventare un problema;

In base a queste considerazioni mi sono posto i primi obiettivi:

  • l’applicazione deve fare due cose in croce, non di più;
  • non è necessario che vada divinamente su mobile;
  • non deve essere perfetto;
  • deve essere un minimo accattivante graficamente;
  • l’applicazione deve passare dalla mia testa al server in pochissimo tempo;

Bene. Come si fa?

Fatti delle domande prima di agire

Più che “come si fa”, innanzitutto mi sono chiesto “che si fa?”

Ho iniziato a buttare giù una prima serie di idee di feature per la prima release dell’applicazione. Non importa da quanto tempo scrivi software, è sempre una delle cose più difficili, perché la mente viaggia ed inizi a tirare dentro di tutto.

Ho così delineato le prime feature di base:

  • devo poter aggiungere/rimuovere dei domini da tenere sotto controllo;
  • voglio ricevere una mail quando il dominio sta per scadere;
  • voglio ricevere una mail quando il certificato SSL sta per scadere;

Oltre a questa feature base, ne ho voluta aggiungere un’altra “bonus”:

  • devo poter aggiungere/rimuovere domini non miei ma che voglio sapere se e quando torneranno liberi;
  • voglio ricevere una mail quando questi domini tornano liberi;

Sono davvero due feature, nulla di più. La cosa bella, però, è che da ognuno di questi punti, apparentemente semplici, si possono scatenare un’infinità di domande:

  • cosa devo salvare di ogni dominio?
  • come avviene il controllo del certificato? e della scadenza del dominio? ogni quanto?
  • quando devo ricevere la mail?

Ecco, questo è il momento in cui scatta il panico, ed è notoriamente più difficile muoversi.

Datti le risposte prima di agire

Quando entro in questa fase è davvero semplice perdere il controllo. Mi è capitato tantissime volte, in passato. Così adotto una tecnica semplicissima: parto da una feature e la riduco all’osso ogni volta che vedo possibilità di personalizzazione. Esempio:

  • Domanda: ogni quanto devo controllare se è il caso di mandare una mail per ricordare dell’imminente scadenza? Devo inviare più di un alert?
  • Risposta: una volta al giorno è più che sufficiente. Zero possibilità di personalizzare l’orario di invio, per il momento, alle 9 di mattina della timezone dell’utente è ok. Un solo alert, 3 giorni prima, basta e avanza.

Qui entra in gioco un concetto fondamentale che prima facciamo nostro e meglio è: le supposizioni che faccio sono, appunto, supposizioni. Possono essere vere o false, ma prima mi butto, prima so se effettivamente la mia supposizione è giusta, e se è sbagliata posso correggere il tiro velocemente.

Insomma, citando Tony Stark: “un bullone sì ed uno no, non devi farmi bello“.

Così alla fine ho delinato le feature principali in modo molto più preciso:

  • avere una lista di domini “sotto controllo”;
  • una volta al giorno faccio un check sul dominio (se richiesto) ed un check sul certificato (se richiesto). Se le scadenze si avvicinano, mando la/le mail;
  • avere una lista di domini non miei, ma che voglio sapere quando torneranno liberi;
  • una volta al giorno faccio un check sul dominio, se è libero mando la mail;

Per rendere l’app più “amichevole”, chiedo all’utente la sua timezone e faccio in modo che qualsiasi alert gli arrivi per le 9 di mattina nel suo fuso orario. Motivo: sono ragionevolmente certo che una mail di una scadenza alle 3 di notte non sia molto comoda.

Bene: possiamo scrivere codice.

Il primo impatto con Jetstream

Come prima cosa, ho avviato un nuovo progetto Laravel e ho installato Jetstream seguendo la documentazione, molto chiara. Ho deciso di installare la versione full-featured con i team (tanto all’inizio si possono disabilitare). Come il titolo lascia intendere, ho scelto il setup con Livewire.

Mi sono preso un po’ di tempo per esplorarlo. Un paio di chicche sono interessanti:

  • la possibilità di aggiungere in modo abbastanza semplice informazioni aggiuntive a quelle già presenti sulla tabella utenti;
  • il sistema di feature, che permette di spegnere/accendere specifiche funzionalità del boilerplate;

Spente le feature non necessarie (team, 2FA e qualche altra chicchetta) mi sono concentrato sulla creazione dei primi componenti. Il boilerplate di base che Jetstream offre è impressionante. A ben pensarci, la mia app deve “gestire” tre cose:

  • Utenti;
  • Domini;
  • Domini non miei da tenere sotto controllo;

Già al momento zero Jetstream mi ha tolto il 33% del lavoro da fare.

Dopo aver creato le prime migration ed i model, passo a Livewire…

Il primo impatto con Livewire

Livewire mi ha messo davanti ad una delle cose più difficili per uno sviluppatore: disimparare.

Ho notato, infatti, che spesso più andiamo avanti e più tendiamo a voler “fare le cose per bene”. Che è paradossale se ci si pensa: spesso studiamo cose che stanno agli antipodi (mi viene in mente lo studio di un linguaggio funzionale venendo dagli oggetti), ed applicare la nostra esperienza a quelle cose, per quanto naturale ci possa venire, è la cosa più sbagliata possibile.

Ci sono un po’ di cose che mi hanno fatto storcere il naso, di Livewire: una su tutte, il fatto che mi piazza le classi con le logiche dei componenti appena generati in “App/Http”, che generalmente associo al backend.

In un primo momento ho sentito un brivido percorrermi la schiena: venendo da React, vedere mischiato un metodo “render()” di una classe piazzata in una cartella chiamata “App/Http” mi ha fatto un po’ senso.

Poi ho ricordato: disimparare. E quindi sticazzi. Buttiamoci, vediamo come va e POI valuto.

Dopo la timidezza iniziale ho preso dimestichezza con il modo in cui i componenti vengono creati e mi sono messo l’anima in pace. Ho fatto tutto in poche ore riuscendo, comunque, a tenere i componenti abbastanza in ordine.

Il primo impatto con Tailwind

Per creare l’interfaccia utente, oltre a Livewire, mi sono affidato a TailwindCSS per avere un’impostazione decente di base.

Ora, il principio alla base di Tailwind è l’ampio uso di utility class. Questo significa che buona parte dei nostri tag HTML saranno infottati di classi css per qualsiasi cosa.

Il concetto è spiegato magnificamente qui.

Anche qui, questa faccenda può piacere o meno. All’inizio ero diffidente poi ho cercato di guardare le cose più dall’alto e ho capito meglio: ci sono talmente tante classi per tante situazioni che il 95% dei casi è abbondantemente coperto.

Per andare più veloce, ad ogni modo, ho “barato”: avendo bisogno di alcuni componenti leggermente più complessi (tabelle, widget ed altre piccole cose), ho comprato i componenti marketing + app su TailwindUI.

Nota: ho comprato il pacchetto completo (marketing + app) per potermi sbrigare anche a fare la home page.

Qui vale la pena fare un’osservazione: sono stati 200 euro ben spesi, se penso che mi hanno evitato ore ed ore di lavoro inutile.

Va detto che TailwindCSS di base è piuttosto scarno e manca di tanti elementi che secondo me andrebbero resi disponibili di default gratuitamente. Ma è una mia opinione e non vale una mazza. In ogni caso peace, non è una grande spesa quindi va bene così.

Alla fine della fiera, in questo modo, per un progetto piccolo o comunque poco esigente, hai tutto quello che serve per consegnare il tuo lavoro in tempi ragionevoli, se non record.

Un ecosistema che funziona

La cosa che mi piace di più dell’ecosistema di Laravel è che funziona. Ho tracciato un po’ il tempo usato per realizzare domain-check.it, ed ecco il breakdown:

  • analisi iniziale: circa 2 ore;
  • creazione del logo/icone/asset con Canva: 2 ore;
  • implementazione dell’applicazione: 12 ore;
  • implementazione dell’admin panel: 0.5 ore con Laravel Nova;
  • realizzazione della home page: 2 ore;
  • deploy sul server di produzione: 1.5 ore con Laravel Forge;

Quindi sì, nel titolo ho detto una stronzata 🙂 Non 48 ore, ma 20.

Questo ovviamente non è stato possibile perché sono bravo o bello, ma perché semplicemente l’ecosistema di Laravel è composto da tanti piccoli strumenti, free o meno, che lavorano in perfetta sinergia tra loro.

Ho già citato Nova e Forge, ma è stato fondamentale avere un sistema di code up and running in poco tempo con Horizon. Gratuito. Anche Jetstream è gratuito, e fa uso di altri package come Fortify.

Insomma, tanta bella carne al fuoco.

Concludiamo!

Millecinquecento parole dopo, cosa ho imparato da questa esperienza?

  • al contrario di quanto pensassi da “esterno”, Laravel Jetstream riesce a dare un notevole contributo, sul serio. Fornisce quello che serve per partire alla grande ed il sistema a feature è facilmente configurabile;
  • per Livewire e Tailwind c’è solo una considerazione da fare: non sono adatti a qualsiasi tipo di progetto, ma fanno il loro lavoro a dovere in caso di progetti non troppo grandi, o in caso di progetti anche grandicelli ma con tante interazioni semplici;

All’inizio dell’articolo avevo supposto come use case ideale l’applicazione piccola.

Adesso inizio a pensare che anche per una di “media” grandezza (in termini sia di utenti che di feature) possa cavarsela senza troppi bagni di sangue.

Vi aggiorno 🙂

Creare un’API GraphQL con Laravel? Ci pensa Lighthouse! – Parte 2

0

Direi che è arrivato il momento di concludere il nostro piccolo viaggio introduttivo alla scoperta di come creare un’API GraphQL con Laravel. Nell’articolo precedente, pubblicato un paio di settimane, fa, avevo spiegato le basi di Lighthouse e di come usarlo per creare, facilmente, un’API GraphQL usando il nostro framework preferito.

L’ultima volta ci siamo lasciati dopo aver visto, un po’ più da vicino, le prime query sulla nostra entità Movie.

Oggi vedremo più da vicino come funzionano le mutation, come vengono gestite le relazioni tra entità e, infine, qualche esempio su altri tool che Lighthouse ci mette a disposizione per facilitarci il lavoro. Pronti? Partiamo dalle…

Creare un’API GraphQL con Laravel? Ci pensa Lighthouse! – Parte 1

1

Ultimamente, nel mio gruppo Facebook preferito, mi trovo spesso a parlare di quali argomenti affrontare su questo blog. L’ultima volta è toccato al Deploy di un’applicazione Laravel su Kubernetes, che pare abbia dato notevoli soddisfazioni.

E oggi? Beh, questa volta daremo uno sguardo, insieme, a come possiamo mettere su senza troppi problemi un’API GraphQL con Laravel. Con l’aiuto di un package davvero speciale: Lighthouse!

GraphQL? Cosa?

Tecnicamente, GraphQL è definibile come un linguaggio da usare per richiedere e manipolare dati via API. Lo ha tirato fuori dal cilindro Facebook, ormai nove anni fa, prima di essere rilasciato pubblicamente nel 2015. Se si vuole studiare nel dettaglio il linguaggio in questione, questa è la fonte ufficiale a cui attingere.

Non mi dilungherò in ulteriori spiegazioni albertoangiolesche, ma gli elementi che bisogna conoscere per iniziare lavorare con delle API GraphQL sono tre:

  • Schema: come il termine suggerisce, è uno schema che descrive nel dettaglio tutte le possibili richieste che un client può fare all’API che costruiremo. Ad ogni chiamata, l’API verificherà tramite questo schema che quella in arrivo sia, effettivamente, una chiamata valida;
  • Query: l’operazione più semplice da fare, in un’API GraphQL, è chiedere dei dati. Una query è esattamente questo: un’operazione di lettura dei dati dal servizio;
  • Mutation: nel momento in cui abbiamo bisogno di modificare qualche dato, allora tocca usare una mutation. Il termine, infatti, descrive ogni operazione di modifica dei dati dell’API;

Rispetto ad una “classica” REST API, ovviamente, ci sono un po’ di differenze. Per citarne alcune:

  • un solo endpoint da interrogare, a differenza di diversi endpoint per REST;
  • per poter usare un’API GraphQL bisogna un po’ impratichirsi nel costruire delle query;
  • in GraphQL è possibile richiedere solo i dati di cui abbiamo effettivamente bisogno, un vantaggio non indifferente;

Due delle API con cui ho lavorato di più in tutta la mia vita sono GraphQL: quelle di Facebook Shopify.

E con Laravel?

Creare una GraphQL API con il nostro framework PHP preferito è, devo ammetterlo, sorprendentemente semplice. Esiste un package, infatti, chiamato Lighthouse, che semplifica di molto la vita dello sviluppatore in questo senso.

Vediamo quindi come installarlo e come prepararlo.

Installazione

Supponendo di avere un progetto “fresco” di Laravel, la prima cosa da fare è installare il package in questione, insieme ad un comodo tool per fare qualche test.

  • Laravel GraphQL Playground è un’utilissima web app, accessibile da browser, che possiamo usare per fare le nostre prime richieste all’API che stiamo costruendo;
  • Pubblicare il file schema di default, invece, ci permetterà di avere a disposizione un primo schema da usare come riferimento per le nostre query. Il package lo userà automaticamente per fare quasi tutto il lavoro!

La prima chiamata API

Visto che so bene quanto vi piace mettere le mani nella ciccia già da subito, vi accontento. Proviamo subito questo package, no?

Andiamo a curiosare nello schema che è stato pubblicato in graphql/schema.graphql.

Possiamo notare principalmente tre cose:

  • Troviamo un tipo User già definito. Corrisponde all’utente di una qualsiasi applicazione Laravel appena creata;
  • All’inizio del file troviamo due definizioni di scalari: Date DateTime. Sono delle definizioni che Lighthouse usa per trasformare automaticamente le date dei timestamp;
  • A metà del file, invece, troviamo le prime due query! Precisamente, il package ci mette a disposizione una query per recuperare tutti gli utenti dell’applicazione, ed una invece per recuperare i dati di un utente specifico;

Possiamo trovare più informazioni su come leggere questo file qui, sul sito di GraphQL, nella sezione dedicata al linguaggio usato per lo schemaDetto questo… facciamo subito una prima chiamata!

Per prima cosa, accediamo a Laravel Tinker per aggiungere al volo un po’ di dati di prova.

Fatto questo, accediamo al Playground andando a visitare http://localhost/graphql-playground. Inseriamo questa query nel pannello a sinistra:

e clicchiamo sul tasto “Play” per eseguire la query.

Già qui possiamo testare una delle cose più interessanti delle API GraphQL: proviamo a togliere “email” dai campi richiesti. La query verrà eseguita lo stesso, ritornando effettivamente gli stessi dati senza, però, la mail dell’utente. Niente male, per non aver scritto nemmeno una riga di codice, no?

Ok, adesso aggiungiamo qualcosa di “nostro”.

Un po’ di cinema!

Ho immaginato una piccola API per gestire film. Quelli che torneremo a vedere al cinema molto presto (spero). Senza strafare, partiamo da qualcosa di molto basilare.

Questo comando genererà il model, la migration ed una factory. Nella migration, aggiungiamo due colonne:

  • title, il titolo del film (string);
  • year, l’anno di uscita (uno small int sarà più che sufficiente);

Nella factory, modifichiamo il metodo definition così:

Non aggiungeremo altro per ora. Non scordiamoci di eseguire php artisan migrate e di generare qualche record di prova per la tabella dei film:

Bene, è tutto.

Torniamo al nostro graphql/schema.graphql. Seguendo la traccia di quello che abbiamo visto prima, dobbiamo aggiungere una definizione per la nostra nuova query. Proprio come per gli utenti, infatti, definiamo…

Cosa abbiamo aggiunto?

  • In fondo al file, la definizione del type Movie, che GraphQL riconoscerà adesso come Movie valido. Gli attributi sono quelli che abbiamo creato con la migration;
  • Tra le query, la prima, quella che ci permette di ottenere (paginati) tutti i film inseriti nel database.
    Nota: in generale preferisco usare la paginazione “CONNECTION”, che fa uso di un cursore. Potete trovare più dettagli a riguardo qui.
  • La seconda query invece è quella che ci permette di ottenere i dati di un singolo film partendo dal suo ID;

Fatto! Possiamo provare la nostra API. E no, non serve scrivere altro codice… bello, vero?

Riapriamo il playground e proviamo la query paginata:

O magari quella di ricerca tramite ID:

Insomma, neanche una riga di codice da scrivere, solo la specifica da compilare. Certo, questo è un caso molto basilare… cosa succederà in situazioni più complesse?

Nella prossima parte di questo articolo, vedremo insieme:

  • come definire ed usare le mutation, per modificare i dati della nostra API;
  • andare oltre le basi del CRUD e creare una logica “custom” più complessa;
  • come rappresentare le relazioni tra model, ed usare la stessa query in casi d’uso totalmente differenti tra loro;
  • altre funzionalità offerte da questo package, come l’uso del throttling per evitare abusi da parte di altri sviluppatori, la validazione dei dati in input, l’ordinamento dei dati e l’uso di middleware per mettere in sicurezza la nostra API!

La seconda parte arriverà tra qualche giorno (update, la seconda parte è qui)… quindi rimanete nei paraggi! Se volete, posso avvisarvi io tramite la newsletter! Potete iscrivervi su questa pagina oppure usare il form a lato.

A presto!