Loopback 4 è un porting di Spring Boot
Se c'è una cosa buona che il faticoso ecosistema JavaScript ha portato nelle nostre vite è un ritorno alla programmazione funzionale. Dopo anni e anni a scervellarsi su oggetti, classi e design pattern, Facebook con i suoi React e Redux ci ha convinti a fare marcia indietro e riconsiderare le funzioni pure, l'immutabilità e la composizione a scapito dell'ereditarietà, delle annotation e della dependency injection. A un tratto il codice diventa potente, performante, leggibile e testabile come non lo è mai stato, e la programmazione orientata agli oggetti (o meglio, alle classi) pare solo un brutto ricordo.
Questo almeno per quanto riguarda il front end. E sul back end? Personalmente per progetti un po' più complessi la mia scelta è ricaduta su Loopback 3, framework di Strongloop (poi acquisita da IBM) che, essendo fortemente basato su Express, riesce a rendere la creazione di un server Node immediata e la sua personalizzazione perlomeno fattibile. Basta definire un modello in un linguaggio che sostanzialmente è un'estensione di JSON Schema e si ha automaticamente un servizio REST che fa tutte le operazioni CRUD sul database. Se poi si vogliono definire funzioni custom si possono creare degli hook a vari livelli dell'architettura, oppure dei middleware in stile Express.
Non vedevo l'ora, quindi, di mettere le mani sulla versione 4 di Loopback, uscita ufficialmente il 10 ottobre 2018. Mi aspettavo più potenza, una migliore documentazione, magari il supporto nativo a GraphQL. Ma soprattutto che rimanesse semplice ed elegante com'era. E invece proprio quest'ultimo punto è stato uno stravoglimento totale, per me incomprensibile. Loopback 4 fa uso di TypeScript (e vabbè, se proprio non potete fare a meno della tipizzazione statica), dei decoratori (e vabbè, basta non abusarne), delle classi (taaaante classi) e ha addirittura un suo sistema di dependency injection!
Da una parte sembra il miglior amico di Angular, framework che non riesco proprio a digerire, dall'altra sembra un porting di Spring Boot. Pare come se i Javisti si fossero riversati nel salotto JavaScript e avessero detto: "Non mi piace qui, dobbiamo riarredare".
Un esempio? Questo è il codice necessario a definire una relazione uno-a-molti in Loopback 3:
{
"name": "TodoList",
"base": "PersistedModel",
"relations": {
"todos": {
"type": "hasMany",
"model": "Todo",
"foreignKey": "todoListId"
}
}
}
Ecco lo stesso tipo di relazione definito in Loopback 4:
import {
DefaultCrudRepository,
HasManyRepositoryFactory,
repository,
} from '@loopback/repository';
import {TodoList, Todo} from '../models';
import {DbDataSource} from '../datasources';
import {inject, Getter} from '@loopback/core';
import {TodoRepository} from './todo.repository';
export class TodoListRepository extends DefaultCrudRepository<
TodoList,
typeof TodoList.prototype.id
> {
public readonly todos: HasManyRepositoryFactory<
Todo,
typeof TodoList.prototype.id
>;
constructor(
@inject('datasources.db') dataSource: DbDataSource,
@repository.getter(TodoRepository)
protected todoRepositoryGetter: Getter<TodoRepository>,
) {
super(TodoList, dataSource);
this.todos = this._createHasManyRepositoryFactoryFor(
'todos',
todoRepositoryGetter,
);
}
}
L'esempio è preso dal tutorial ufficiale, che al momento in cui scrivo è anche errato (ho dovuto aggiustare guardando il sorgente degli esempi).
Inoltre per creare un unico endpoint REST è necessario:
- Creare una classe di modello
- Creare una classe datasource
- Creare una classe repository
- Creare una classe controller
La classe modello descrive le proprietà del modello tramite attributi di istanza e decoratori, mentre prima bastava un po' di JSON.
La classe datasource serve solo a iniettare la configurazione JSON simile a quella che c'era in Loopback 3.
La classe repository serve solo a iniettare la classe datasource.
La classe controller espone tutti i metodi CRUD di base, oportunamente decorati, risultando in circa 130 righe di codice quando in Loopback 3 ne servivano 0.
Parafrasando Bender, mi viene voglia di creare un Loopback tutto mio, con blackjack e squillo di lusso. Anzi, senza blackjack e neanche le squillo, ma almeno più funzionale.
# IceOnFire