Un confronto tra React, Angular, Vue.js e Svelte: Routing e HTTP api

di Morgan Pizzini, in HTML5,

In questo articolo vogliamo proseguire il discorso iniziato nell'articolo precedente), in cui abbiamo visto i pro/contro di ogni tecnologia front-end, i consigli generali per la scelta e i primi passi per iniziare un progetto. In un altro script) abbiamo invece trattato come condividere le informazioni tra i vari componenti dell'applicazione, requisito necessario per evitare lo spaghetti-code e porre le basi per un'architettura che può essere estesa e completata in corso di sviluppo. Tutti i framework front-end presi in esame si basano sui principi di SPA (Single Page Application). A differenza di siti web tradizionali è teoricamente possibile strutturare facilmente tutta l'applicazione sulla homepage, inserendo e rimuovendo i vari componenti nella pagina, ma, per mantenere un buon livello di usabilità, è sempre consigliato creare sezioni, o route, che consentano di suddividere l'applicazione in aree tematiche alle quali l'utente può recarsi, facendo si che l'applicazione recuperi le informazioni necessarie per la rappresentazione, siano esse componenti o dati provenienti da una Web API.

Come già fatto nelle precedenti pubblicazioni, il punto di partenza sarà sempre un progetto nuovo. Nei primi esempi andremo a effettuare una richiesta a una web api mostrando i risultati sulla pagina. Successivamente suddivideremo l'applicazione creando una pagina alle quale potremmo arrivare passando come parametro nell'url l'id dell'elemento selezionato come accade in situazioni master-detail (lista di oggetti e dettaglio).

L'oggetto recuperato dalla web api, per praticità, avrà sempre la stessa struttura: un id e un nome. Dove necessario la classe verrà chiamata Item.

HTTP con Angular

Benché non esista un vero e proprio componente adibito alla comunicazione con api HTTP, Angular offre la possibilità di utilizzare degli oggetti, chiamati services, che consentono di essere creati come singleton all'interno del modulo corrente. Questo approccio ha vari vantaggi, soprattutto per quanto riguarda la condivisione dei dati all'interno dell'applicazione, nel nostro caso ci consentirà di istanziare un HttpClient e utilizzarne dei metodi per recuperare le informazioni richieste.

ng g service services/sample

Il comando precedente va a interrogare la CLI di Angular e crea un nuovo servizio all'interno della cartella app/services chiamato SampleService.

import { Injectable } from '@angular/core';

@Injectable()
export class SampleService {
  constructor() { }
}

La prima modifica da effettuare sarà inserire all'interno del decoratore Injectable la proprietà providedIn assegnandole come valore root. In questo modo il servizio verrà creato ed iniettato nel modulo del componente che ne richiederà un'istanza. Avremo poi bisogno di un'istanza di HttpClient alla quale girare la richiesta. A margine di questa modifica va ricordato che Angular è un framework altamente modulare, infatti per poter utilizzare il tipo HttpClient avremo bisogno di importare il modulo HttpClientModule, il che trasformerà il nostro codice come nell'esempio.

// service

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

@Injectable({
  providedIn: 'root'
})
export class SampleService {
  
  constructor(private http: HttpClient) { }

  getItems() {
    return this.http.get<Item>("web-api-endpoint");
  }
}

// modulo
import { HttpClientModule } from '@angular/common/http';
@NgModule({
  imports: [
    ...
    HttpClientModule,
  ],
  ...
})
export class AppModule {}

Il componente che utilizzerà il servizio sarà dunque aggiornato inserendo il riferimento al servizio e una variabile per salvare la risposta

import { Component } from '@angular/core';
import { SampleService } from '.services/sample'

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {
  items: Observable<Item>;

  constructor(service: SampleService) {
    this.items = service.getItems()
  }
}

Strutturiamo la parte HTML in modo che visualizzi la lista di oggetti e ci dia già la possibilità di navigare verso una pagina dettaglio "detail/id"

<div ngFor="let item of items | async">
    <a href="/detail/{{item.id}}">{{item.name}}</a>
</div>

HTTP con React

Per esperienza abbiamo imparato che la semplicità e l'immediatezza è il primo punto di forza di React, infatti per poter chiamare un servizio basterà utilizzare il metodo fetch messo a disposizione dal framework, valorizzando poi una proprietà dello state per eseguire il rendering della pagina.

import React, {Component} from 'react';

class App extends Component {
  state = {
    items: []
  }
  componentDidMount() {
    fetch('web-api-endpoint')
    .then(res => res.json())
    .then((data) => {
      this.setState({ items: data })
    })
  }
  render () {
    return (
        <div>
        {items.map((item) => (
            <a href="/detail/{item.id}">{item.name}</a>
        ))}
        </div>
      
    );
  }
}

Data la necessità di visualizzare la lista il prima possibile inseriamo la chiamata all'interno del metodo componentDidMount. All'interno del codice HTML eseguiamo un ciclo inserendo tanti link quanti sono gli oggetti. Come per la parte Angular, si tratta di un template che modificheremo nei capitoli successivi quando analizzeremo la navigazione.

HTTP con Vue

Chiamare una api HTTP da un'applicazione Vue potrebbe non essere una cosa scontata. Data la bassa disponibilità di API native, avremo bisogno di utilizzare una libreria: la più utilizzata a livello di community è axios installabile tramite il seguente comando.

npm install axios

Essa fornisce una serie di funzioni che ci permetteranno di creare e configurare qualsiasi chiamata HTTP. Il componente avrà quindi la struttura seguente.

<template>
    <a v-for="item in items" :key="item.name" href="/detail/{{item.id}}">
      {{ item.name }}
    </a>
</template>

<script>
import axios from "axios";

export default {
  name: 'App',
  data () {
    return {
      items: null
    }
  },
  mounted () {
    axios
      .get('web-api-endpoint')
      .then(response => (this.items = response.data))
  }
}
</script>

Come per React, utilizziamo il metodo mounted per effettuare la chiamata il prima possibile. Utilizzando la libreria prendiamo la risposta dall'endpoint tramite una chiamata get e valorizziamo un array dello state, nel codice HTML iteriamo sugli elementi contenuti in questa lista e visualizziamo il link per ognuno di essi.

HTTP con Svelte

Abbiamo imparato ad apprezzare Svelte per la sua facilità e immediatezza nelle operazioni più comuni. Data la sua giovane età, contiene molti spunti provenienti dagli altri framework e non dobbiamo quindi stupirci se la scrittura del codice per interrogare una api HTTP somigli molto a quanto già visto.

<script>
  import { onMount } from "svelte";
  
  let items;
  onMount(async () => {
    await fetch(`web-api-endpoint`)
      .then(r => r.json())
      .then(data => {
        items = data;
      });
  })

</script>
{#if items}
  {#each items as item }
    <a href="/detail/{item.id}">
      { item.name }
    </a>
  {/each}
{:else}
  Caricamento...
{/if}
2 pagine in totale: 1 2
Contenuti dell'articolo

Commenti

Visualizza/aggiungi commenti

| Condividi su: Twitter, Facebook, LinkedIn

Per inserire un commento, devi avere un account.

Fai il login e torna a questa pagina, oppure registrati alla nostra community.

Approfondimenti