Design per app iOS supportato da API

1

Mi chiedevo se qualcuno là fuori avesse suggerimenti generali su come strutturare un'app iOS supportata da un'API REST. Ci sono fondamentalmente due approcci a questo che ho pensato di

Chiamate API posizionate ad hoc nei controller della vista.

In questo approccio il controller di visualizzazione ha lo stato che recupera dal back-end come un oggetto User e quindi esegue il rendering del profilo dell'utente. Questo approccio è semplice in quanto non è necessario gestire alcuna sincronizzazione. Devi semplicemente recuperare i dati quando ne hai bisogno, come se stessi facendo il rendering di una pagina web.

Gli svantaggi di questo approccio sono duplici:

  • Condizioni di gara nella visualizzazione / aggiornamento dei modelli
  • Problemi di sincronizzazione con istanze di modelli in altri controller di vista

Per illustrare il primo punto, supponiamo di avere alcuni conteggi delle notifiche sul profilo utente. Quando visiti la pagina del profilo, recuperi l'oggetto utente ma desideri anche aggiornare l'utente quando visita una determinata scheda. Quindi hai due chiamate:

GET /rest/user  # gets the user
POST /rest/user  # clears notifications

Il risultato è una condizione di competizione tra il recupero dell'utente e l'aggiornamento del conteggio delle notifiche. Puoi recuperare un oggetto utente senza che i notificazioni siano cancellati.

Per il secondo punto, è possibile aggiornare l'oggetto utente, ma poi avere altri controller di visualizzazione che dipendono dall'oggetto utente aggiornato. In qualche modo è necessario comunicare l'aggiornamento a questi controller di visualizzazione.

Considera l'app come una cache con un archivio dati che si sincronizza con l'API

In questo approccio, tutti gli aggiornamenti e gli arresti del modello avvengono localmente tramite un'interfaccia dati. L'interfaccia dati decide quando sincronizzarsi al back-end e, se non ha alcuni dati localmente, blocca i chiamanti finché i dati non sono disponibili. Il lato negativo di questo approccio è che è più complicato, devi gestire l'invalidazione della cache e non mi è chiaro come implementare la sincronizzazione.

Voglio seguire questa strada, ma non sono sicuro di come procedere. Quindi, ho alcune domande:

  • Questo archivio dati sembra l'approccio giusto?
  • Esistono librerie che implementano un archivio dati come questo? O esempi di progetti che seguono questo percorso?
  • I controller di visualizzazione possono recuperare istanze di oggetti attraverso l'archivio dati, ma questi controller di visualizzazione devono ancora essere a conoscenza degli aggiornamenti comunicati in qualche modo e non sono sicuro di come comunicare tali aggiornamenti.
posta Eric Conner 04.11.2016 - 16:54
fonte

1 risposta

2

Penso che tu abbia presentato due buone opzioni qui. Quale, o combinazione di entrambi, funzioni meglio per te dipende in realtà dai dati che stai lavorando e da come vuoi usarli. Probabilmente non c'è abbastanza contesto per una raccomandazione conclusiva, ma qui ci sono alcune idee.

Richieste ad hoc

Raccomando di non consentire mai ai tuoi controller di visualizzazione di accedere direttamente a un'API. Nella tua prima proposta vorrei almeno introdurre un livello "servizio" o "repository". Iniettare servizi nei propri controller di visualizzazione e richiedere al controller di eseguire il proprio intervento per quanto riguarda il modello di dominio ("aggiorna profilo utente" o qualsiasi altra cosa). Ciò consente almeno di raggruppare più richieste API in un'unica operazione logica. Un servizio può effettuare più richieste e quindi chiamare un blocco di completamento con risultati di successo / fallimento aggregati. Un servizio ti offre anche un posto per introdurre il caching del client, prevenire richieste duplicate e così via.

Lo userei se i dati che hai presentato sono raramente condivisi su schermi diversi o devono essere aggiornati frequentemente in modo che una cache lato client possa non essere utilizzata.

Richieste REST / SOAP memorizzate nella cache

Il caching HTTP attraverso un oggetto di servizio condiviso da più controllori potrebbe darti una visione coerente dei tuoi modelli, a condizione che le rotte dell'API rispondano con dati isolati (ovvero una richiesta a una rotta non invalida la risposta in cache da qualche altra rotta).

Una versione più complessa potrebbe includere servizi che memorizzano i risultati in Core Data o in qualche altro archivio lato client che può essere interrogato in modi che non corrispondono esattamente agli endpoint API. L'aumento dei risultati in un negozio comune può consentire una risposta API per aggiornare molte entità correlate. Come hai notato, è necessario disporre di una politica per quando eliminare i dati da questo archivio (eliminare le istruzioni dall'API, le convenzioni su quando eliminare i dati non visualizzati nella risposta API più recente, le date di scadenza sui dati stessi o presto). Ho trovato il pattern link per gli oggetti included utili qui come un modo per una risposta dell'API per aggiornare molti modelli client correlati.

Lo userei se i tuoi dati sono strongmente interconnessi, se di solito aggiorni solo piccole porzioni dell'intero insieme di dati alla volta e puoi riutilizzare il resto, se il cliente vuole interrogare gli stessi dati in un sacco di diversi modi, o se vuoi supportare alcune interazioni offline con i dati una volta che ce l'hai.

Sincronizzazione

Quando dici "sincronizzazione", penso alle API che forniscono un flusso di eventi di modifiche dall'ultima sincronizzazione. Questi eventi possono quindi essere riprodotti su un client per aggiornarne la cache locale. A seconda del caso d'uso, ciò potrebbe richiedere anche la possibilità di richiedere un'istantanea del modello in un momento recente in cui iniziare, in modo che ogni cliente non tenti di riprodurre l'intera cronologia degli eventi in continua crescita. In questo modo un cliente che è caduto sufficientemente aggiornato può rinunciare, richiedere uno snapshot recente e iniziare la sincronizzazione da lì.

Questo tipo di sincronizzazione può funzionare bene per i flussi di aggiornamenti che arrivano in modo imprevedibile e non in risposta all'azione dell'utente del client, ma richiede un back-end in grado di produrre tale flusso di eventi. A seconda delle esigenze, questa potrebbe essere una sequenza di messaggi in una sala IRC o trasformazioni operative che aggiornano un documento (ad esempio Etherpad).

Lo utilizzerei per aggiornamenti costanti o imprevedibili ma frequenti o se il tuo dominio consentirebbe la modifica completa offline dei tuoi dati e la risincronizzazione di tali modifiche in seguito.

    
risposta data 05.11.2016 - 02:12
fonte

Leggi altre domande sui tag