Alessio Biancalana Grab The Blaster di Alessio Biancalana

Elixir per idioti /7, mettiamo le mani in pasta con Phoenix Framework

Visto che abbiamo scavato sempre più a fondo nelle basi del linguaggio, proviamo a fare qualcosa di più cicciotto con il framework web del momento, ovvero Phoenix. Phoenix Framework è, come abbiamo appena detto, un framework per il web che ci permette di sviluppare il nostro backend in Elixir seguendo quello che a grandi linee sembra un pattern MVC. In realtà come tutti i framework di ultime generazione, può essere piegato per sviluppare backend REST/RESTful. Ma con tutti questi acronimi abbiamo già messo troppa carne al fuoco.

Dato che abbiamo già un’installazione funzionante di Elixir, possiamo usare Mix per installare il pacchetto di Phoenix:

$ mix archive.install https://github.com/phoenixframework/archives/raw/master/phx_new.ez

Per quanto riguarda le utility che ci facilitano la vita sul frontend, avremo bisogno anche di NodeJS. Su macOS io lo installo tramite Homebrew:

$ brew install node

Su una distribuzione Linux Debian-based come Ubuntu dobbiamo invece scaricare il pacchetto più aggiornato o servirci direttamente dei repository ufficiali:

$ sudo apt-get install nodejs

Per poi fare un link mano in modo che il comando node faccia partire NodeJS.

$ ln -s /usr/bin/nodejs /usr/bin/node

Una volta dati questi comandi, siamo pronti. In teoria avremmo bisogno di configurare anche un database PostgreSQL in locale in modo da poter salvare eventuali dati, ma questo è già qualcosa di più avanzato. Abbiamo una serie di task Mix che ci aiutano con la creazione di un nuovo progetto; attraverso mix phx.new possiamo creare una nuova struttura e soprattutto definire di cosa abbiamo bisogno. Possiamo escludere il frontend e possiamo escludere la parte di interfaccia al database se non ci servono.

Per il mio esempio escluderò di aver bisogno del database.

$ mix phx.new my_phoenix_demo --no-ecto

Abbiamo di seguito un output dei file creati e qualche indicazione utile per cominciare a muovere i nostri primi passi con, dopo tanto parlare di massimi sistemi, un esempio di applicazione reale:

* creating my_phoenix_demo/config/config.exs
* creating my_phoenix_demo/config/dev.exs
* creating my_phoenix_demo/config/prod.exs
* creating my_phoenix_demo/config/prod.secret.exs
* creating my_phoenix_demo/config/test.exs
* creating my_phoenix_demo/lib/my_phoenix_demo/application.ex
* creating my_phoenix_demo/lib/my_phoenix_demo.ex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/channels/user_socket.ex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/views/error_helpers.ex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/views/error_view.ex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/endpoint.ex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/router.ex
* creating my_phoenix_demo/lib/my_phoenix_demo_web.ex
* creating my_phoenix_demo/mix.exs
* creating my_phoenix_demo/README.md
* creating my_phoenix_demo/test/support/channel_case.ex
* creating my_phoenix_demo/test/support/conn_case.ex
* creating my_phoenix_demo/test/test_helper.exs
* creating my_phoenix_demo/test/my_phoenix_demo_web/views/error_view_test.exs
* creating my_phoenix_demo/lib/my_phoenix_demo_web/gettext.ex
* creating my_phoenix_demo/priv/gettext/en/LC_MESSAGES/errors.po
* creating my_phoenix_demo/priv/gettext/errors.pot
* creating my_phoenix_demo/lib/my_phoenix_demo_web/controllers/page_controller.ex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/templates/layout/app.html.eex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/templates/page/index.html.eex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/views/layout_view.ex
* creating my_phoenix_demo/lib/my_phoenix_demo_web/views/page_view.ex
* creating my_phoenix_demo/test/my_phoenix_demo_web/controllers/page_controller_test.exs
* creating my_phoenix_demo/test/my_phoenix_demo_web/views/layout_view_test.exs
* creating my_phoenix_demo/test/my_phoenix_demo_web/views/page_view_test.exs
* creating my_phoenix_demo/.gitignore
* creating my_phoenix_demo/assets/brunch-config.js
* creating my_phoenix_demo/assets/css/app.css
* creating my_phoenix_demo/assets/css/phoenix.css
* creating my_phoenix_demo/assets/js/app.js
* creating my_phoenix_demo/assets/js/socket.js
* creating my_phoenix_demo/assets/package.json
* creating my_phoenix_demo/assets/static/robots.txt
* creating my_phoenix_demo/assets/static/images/phoenix.png
* creating my_phoenix_demo/assets/static/favicon.ico

Fetch and install dependencies? [Yn] Y
* running mix deps.get
* running cd assets && npm install && node node_modules/brunch/bin/brunch build
* running mix deps.compile

We are all set! Go into your application by running:

    $ cd my_phoenix_demo

Start your Phoenix app with:

    $ mix phx.server

You can also run your app inside IEx (Interactive Elixir) as:

    $ iex -S mix phx.server

L’unica cosa che ci viene chiesta è se vogliamo già scaricare le prime dipendenze e cominiciare con una prima compilazione del progetto Elixir e degli asset grafici (JavaScript e quant’altro).

Possiamo provare subito il nostro hello world, entrando nella directory che abbiamo creato e dando i comandi che ci consiglia lo stesso Phoenix:

$ cd my_phoenix_demo
$ mix phx.server
Compiling 12 files (.ex)
Generated my_phoenix_demo app
[info] Running MyPhoenixDemoWeb.Endpoint with Cowboy using http://0.0.0.0:4000
19:23:19 - info: compiled 6 files into 2 files, copied 3 in 1.3 sec

Puntando il nostro browser all’indirizzo http://localhost:4000/ possiamo vedere la nostra applicazione che gira.

Phoenix hello world

All’interno della directory abbiamo tutti i file della nostra nuova applicazione Phoenix, tra cui i controller, il router, e i template HTML (file di estensione .eex). Proviamo a vedere com’è fatto il router, che è un po’ il punto nevralgico dove avviene lo smistamento delle chiamate al nostro server:

# lib/my_phoenix_demo_web/router.ex

defmodule MyPhoenixDemoWeb.Router do
  use MyPhoenixDemoWeb, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

  scope "/", MyPhoenixDemoWeb do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
  end

  # Other scopes may use custom stacks.
  # scope "/api", MyPhoenixDemoWeb do
  #   pipe_through :api
  # end
end

Quello del router è un DSL specifico creato apprositamente per specificare gli endpoint della nostra applicazione e redirezionare le richieste allo specifico controller di competenza. In questo caso, abbiamo solo una rotta che rappresenta la home page.

Proviamo ad aggiungere una rotta nuova che mostri all’utente una pagina con la data odierna. Modifichiamo il router in questo modo:

scope "/", MyPhoenixDemoWeb do
  pipe_through :browser # Use the default browser stack

  get "/", PageController, :index
  get "/today-date", PageController, :date
end

In questo modo ogni volta che fare una richiesta a /today-date, verrà eseguita la funzione date all’interno del PageController (che è appunto un controller. Lo dice la parola stessa). Andiamo aggiungerla quindi:

# lib/my_phoenix_demo_web/controllers/page_controller.ex

defmodule MyPhoenixDemoWeb.PageController do
  use MyPhoenixDemoWeb, :controller

  def index(conn, _params) do
    render conn, "index.html"
  end

  def date(conn, params) do
    today_date = Date.utc_today() |> Date.to_string
    render conn, "date.html", today_date: today_date
  end
end

Ho appunto creato la nuova funzione che prende la data, fa uso del pipe operator di cui abbiamo già parlato e inietta il valore in un template che poi renderizza. Andiamo quindi a creare questo template, che sarà il file lib/my_phoenix_demo_web/templates/page/date.html.eex:

<p>Today is: <%= @today_date %></p>

Facciamo ripartire il server con mix phx.server. Puntiamo poi il browser su http://localhost:4000/today-date e via, il gioco è fatto. potremo osservare l’agognato risultato del nostro lavoro. E non finisce qui: quello che abbiamo imparato molto a grandi linee è come sviluppare una feature seguendo un pattern MVC di base, ma possiamo fare anche altro. Per esempio, io uso Phoenix per fare bootstrap anche solo di applicazioni server-side che forniscano API RESTful.

Phoenix today date application

Per come la vedo io, Phoenix nasconde molto delle vere potenzialità (e dei veri problemi) che Elixir può offrire, ma non è che un grandissimo trampolino di lancio e una porta di facilissimo accesso per chi è un alchimista in erba e vuole cominciare a scrivere codice con una curva di apprendimento bassissima.

Vai alla parte 6

Instagram, tra founder che lasciano e una piattaforma stravolta

Instagram on iPhone

Nella rete le notizie corrono veloci, e ormai tutti sanno che Kevin Systrom e Mike Krieger, i due fondatori di Instagram, stanno lasciando la società. Ma questo perché accade? Il New York Times ne parla in maniera abbastanza nebulosa, ed è pur vero che segnali più forti non farebbero bene né ai ragazzi né alla società stessa:

Mr. Systrom and Mr. Krieger did not give a reason for stepping down, according to the people, but said they planned to take time off after leaving Instagram. Mr. Systrom, 34, and Mr. Krieger, 32, have known each other since 2010, when they met and transformed a software project built by Mr. Systrom into what eventually became Instagram, which now has more than one billion users.

Biasimarli proprio non posso. Questi due ragazzi hanno costruito un’applicazione in una notte, che consentisse di scattare delle foto in formato 1:1, ritoccarle per dar loro un effetto vintage (analogico), e condividerle su una timeline. Nessuno di loro (e nessuno in generale) ha mai voluto diventarci ricco, né immaginava che questo piccolo prototipo portasse a uno dei più grandi business del nostro tempo.

Nessuno di loro immaginava di aver dato il via a quella che nel bene o nel male possiamo definire come una rivoluzione culturale ed estetica, che lega ancor più indissolubilmente un essere umano col suo modo di apparire, creando distorsioni e crepe nello specchio della realtà.

Instagram non è più quello che era una volta, e forse il social networking nel suo complesso non è più quello di un tempo. Ce lo ricorda Andrea condividendo John Oliver:

“Facebook’s global expansion has been linked to political turmoil overseas, so maybe their ads should focus less on how they “connect the world” and more on why connecting people isn’t always the best idea.”

E sempre Andrea qualche settimana fa mi ha ricordato in maniera leggermente più gradevole di come abbia fatto il mio analista come sia importante l’essenza dell’essere qui, ovvero che non serve a niente essere proiettati altrove, e bisogna mantenere il fulcro di sé stessi, ancoràti al presente. A volte anche partendo dai propri “luoghi” online.

È in questa sagra dell’apparire innestata nella decadenza della civiltà dell’informazione che è da contestualizzare l’addio di Systrom e Krieger. E forse è ora di tornare a creare i nostri spazi piuttosto che aderire ad un sistema economico1 che arricchisce inabili ai danni dei contenuti di qualità.

  1. Dove la moneta è l’apparire unito a delle metriche che più effimere, alterabili e soggettive non si può. Tra l’altro, può ancora essere considerato “contenuto” qualcosa che viene prodotto e pubblicato su Instagram? O i post sono talmente tanto effimeri, e noi talmente sommersi di input da aver bisogno della funzionalità di “save post” per ricordare dove sono le cose interessanti che abbiamo visto, che la pubblicazione può essere catalogata nei “riflessi”, come se anche i post fossero storie, raccontate e poi sparite, che hanno l’unico pregio di rimanere visibili sul profilo? Ma soprattutto, che frase lunghissima e difficile da leggere ho partorito? Però se vi leggevate le note a piè di pagina di Foster Wallace, adesso vi beccate anche le mie. Il mio pregio è che io non mi impicco. 

Un giro di ferie nelle Marche descritto dalla mia lei

Anche se ormai a qualche settimana di distanza dalle nostre ferie, Agnese ha deciso di raccontare il viaggio che abbiamo fatto nelle Marche, regione nella quale ci sono parecchi amici che non voglio mai, e dico mai, perdere di vista.

Adoro la sua scrittura, ma mi piace riportare in particolare un passaggio su Macerata:

Il secondo giorno Dio creò la seconda colazione e vide che era cosa buona e giusta. Soprattutto buona. Fatta una prima colazione in albergo per dovere di cronaca, incontriamo gli amici di Alessio da Maga Cacao, una cioccolateria che ha una selezione di caffè talmente ampia che quando ho scelto, ero invecchiata di un anno. Golosa è dire poco. Trascorriamo la mattinata tra chiacchiere che scorrono facilmente e fette di torta ad accompagnare. Ci salutiamo dicendoci che ci vedremo ancora, quantomeno per assaggiare il cinghiale che fa la mamma di uno di loro. Ce ne andiamo con il sorriso che ti lascia il calore di persone belle.

Che poi non è nient’altro che la verità. La più pura delle verità.

Cosa mi hanno lasciato le Marche? Sicuramente voglia di olive ascolane, che non sono mai abbastanza. Qualche chilo in più generosamente segnato dall’impietosa lancetta della bilancia. Sorrisi. Lacrime di gioia.

E poi regà, i vincisgrassi.

Di compleanni, blogging e social networking

Oggi è il compleanno del blog di Andrea. Andrea è uno fico, uno che seguo stabilmente e che seguo da un sacco di tempo. Ad aiutarmi a farlo, oltre il feed RSS, anche un bellissimo canale Telegram dove condivide post e sporadicamente qualche piccola riflessione. Andrea lo trovo fico (sì, ancora) perché non si arrende, e perché attraverso il suo approccio al web fa spesso riflettere anche me, che non ho smesso di tenere un blog in più di dieci anni, e che considero Grab The Blaster una tra le cose più importanti che ho attraverso le sue molteplici incarnazioni e le miriadi di stili di scrittura che contiene.

Non ci pensavo, ma questo angolo di web che continua a raccogliere le mie nerdesche memorie ha compiuto undici anni qualche mese fa. Oltre a stappare le bollicine, trovo molto vicino quello che ha scritto Andrea, soprattutto perché alcune volte mi sono divertito, durante questi anni, a guardarmi indietro e notare come il mio scrivere si sia modificato, insieme agli argomenti che trattavo. Dalle riflessioni di ordine personale, ai giochi per PlayStation, a Linux, al web, alla programmazione. Alla programmazione funzionale.

Ma soprattutto dal quindicenne che ero, con i punti esclamativi e le virgole messi in un certo modo, all’adulto che sono, con tutto quello che ne deriva. Guardare indietro su questo blog è come guardare un intimo album di foto che in fondo è la più fedele rappresentazione di me che esiste. E non esiste social che tenga, non esiste foto di copertina o foto del profilo che possa compensare quello che è capace di scrivere una persona, nel bene o nel male, ma soprattutto senza limitazioni dovute ai caratteri e alle logiche insite nella piattaforma.

Guardiamoci intorno. Avevamo una cosa meravigliosa, una piazza aperta e decentralizzata dove ognuno poteva essere il nuovo Martin Lutero e affiggere le sue novantacinque tesi1. Abbiamo finito per trasformare anche questo sogno in qualcosa di centralizzato, dove l’Occhio di Sauron può vedere tutto e se gli sfuggi sei tu che ci perdi in visibilità. Ma visibilità di cosa poi? Dei contenuti che lui, grazie a quello che noi scienziati chiamiamo “machine learning”, ovvero una sconfinata distesa di esempi di “questo va bene - questo va male”, vuole proporci.

È per questo che mi ritrovo particolarmente nelle parole di Andrea:

Per me è il ricordo di non abbandonare me stesso a luoghi altri dove il mio contenuto si perderebbe in rigagnoli fatti di algoritmi e logiche di business avulse ad esso.

Altrove, io mi perdo. Qui è uno dei pochi posti dove ritrovo me stesso, digitalmente e materialmente parlando. Ed è per questo motivo che non credo che abbandonerò mai il mio blog.

Ho cominciato a postare in maniera più consistente su Instagram. Lo trovo carino, mi permette di associare ad un’immagine in formato 1:1 (tipo Polaroid) un piccolo post-it con dei pensieri volatili. È però qualcosa che considero di seconda categoria, non perché non siano contenuti di qualità2, ma perché nel momento in cui tappo il pulsante “Pubblica”, quelle foto e quei pensieri vanno a finire sul server di qualcun altro. Qualcun altro che un giorno chiuderà baracca e burattini, e andrà tutto perso. Qualcun altro che nasconde ciò che penso e ciò che vedo per privilegiare post sponsorizzati di utenti con i follower spesso e volentieri comprati. Un regno dove le metriche, volentieri alterate, hanno la meglio sulla qualità. Un regno dove malvolentieri ti metti il cuore in pace sul fatto che se fai qualcosa di strabiliante non verrai notato da nessuno.

Certo, in realtà nemmeno il blog rappresenta più questo. Sono sicuramente finiti i tempi in cui se avevi un blog rischiavi di venire letto da milioni di persone. Sono ormai questi i tempi in cui pubblicherò questo post, poi lo condividerò su Facebook, e forse riceverò come è normale che sia più commenti lì che qui. Ma non mi disturba: l’importante è che il mio blog sia il fulcro di tutto questo. E che permanga.

  1. Questa viene dal mio tema di maturità, che era su Internet e i social network dato che in quel periodo andavano un sacco di moda. Nonostante fosse il mio pane quotidiano da allora, specie grazie a Linux, mi ricordo che scriverne la conclusione è stato come cavare il sangue dalle rape. 

  2. Instagram mi aiuta. Ci sono foto di workstation molto belle, panorami mozzafiato, note mentali lasciate lì dai più e tanta fotografia “da cellulare” molto bella. Purtroppo tutto questo è inabissato da una pletora di professionisti della finzione, ma ok, fa parte del gioco. 

Costruendo la nuova home page del New York Times

Il New York Times mi affascina sempre tantissimo, data l’avanguardia che propone nei processi di progettazione del software e nel design. In questo articolo, come hanno progettato la nuova home page trattando anche i feedback dei lettori.