Come descrivere un cambiamento architettonico che infrange intenzionalmente gli standard REST?

36

Sto proponendo modifiche a un progetto software molto scarsamente architettato che soffre di una moltitudine di problemi. Ad un livello elevato il progetto utilizza Angular sul front-end e utilizza varie API REST; che è tutto fantastico (non vedo la necessità di cambiare la nostra tecnologia o strumenti). Il problema è che il codice base è sproporzionatamente più grande nell'interfaccia utente rispetto alle API sul lato server. Gran parte della business logic risiede nell'interfaccia utente, con le API REST come semplici interfacce database CRUD al livello dell'interfaccia utente.

Ad esempio, un POST al cliente creerà un record del cliente, mentre un PUT modificherà quel cliente. Non molto di più, e non molto di meno. Tuttavia, la nostra logica aziendale è più impegnativa di quella. Il processo generale di creazione di un cliente fa molto di più che inserire 1 record del database. Fornirà dati in altre tabelle necessarie, eseguirà determinate convalide e calcoli, ecc. Preferirei creare una singola chiamata POST / PUT che incapsula tutto questo comportamento, alleggerendo il carico del client che consuma.

Quindi il mio punto di vista è che questa orchestrazione globale dovrebbe vivere sul server (dove abbiamo il controllo completo, i registri, ecc.), non sull'interfaccia utente, ma un controargomento è che questo approccio non sarebbe più RESTful. Quindi sono incerto su come meglio descrivere questo approccio quando la mia raccomandazione è di continuare con lo stack tecnologico esistente, ma implementare cambiamenti fondamentali nelle posizioni in cui il codice appartiene.

    
posta Ben Harrison 21.06.2018 - 16:09
fonte

5 risposte

49

I am uncertain how to best describe this approach when my recommendation is to continue with the existing technology stack, but implement fundamental shifts in the locations where code belongs.

Service oriented architecture .

Stai proponendo di riprogettare il tuo sistema in modo che le tue regole aziendali e i tuoi dati siano nella stessa posizione. Questa è effettivamente la definizione di un servizio ; guarda il discorso di Udi Dahan su Ricerca dei limiti di servizio .

Barra laterale: come notato da Eric, questo non ha nulla a che fare con "REST". Non vi è assolutamente alcun motivo per cui non sia possibile inserire un'API REST (ovvero un'API che soddisfi i vincoli di stile architettonico REST ) di fronte al tuo servizio. Ma questo potrebbe non essere ovvio per le persone che capiscono che REST significhi una mappatura delle operazioni del database con i metodi HTTP.

Può o non può valere la pena investire nel cambiare la comprensione del pubblico di REST.

    
risposta data 21.06.2018 - 16:29
fonte
29

REST non è CRUD. Quella "controargomentazione" si basa su una comprensione fondamentalmente errata di ciò che REST è. Non ho visto nulla nel tuo post che indichi che il tuo cambiamento renderebbe la tua API più o meno RESTful.

    
risposta data 21.06.2018 - 16:18
fonte
23

Un'altra cosa da tenere a mente è la seguente ... Non convalidare il lato server delle regole di business, significa che ti fidi implicitamente di tutto ciò che entra, attraverso una richiesta POST, è valido.

Ciò significa che, ad esempio, mentre la tua applicazione angolare potrebbe verificare se il cliente ha una fascia di età valida e garantisce che gli utenti legittimi ottengano il feedback corretto, chiunque conosca l'url della tua API può fare una richiesta POST contenente alcuni non legittimi valori che non sarebbero più validi.

Quindi il mio suggerimento sarebbe spostare le regole aziendali sull'API, lasciare che convalidi l'input e restituire gli errori appropriati (o forse solo i codici che indicano cosa è andato storto) nel corpo della risposta. Questi codici possono essere utilizzati dall'applicazione di front-end per indicare cosa è andato storto.

    
risposta data 22.06.2018 - 10:15
fonte
10

Per aggiungere altre buone risposte qui:

La tua interfaccia, REST o altro, non dovrebbe essere vincolata sulla base di una sorta di ipotesi sui dettagli dell'implementazione. Questo è completamente antitetico alla nozione di servizi come livello di astrazione.

Uno dei principali vantaggi dell'utilizzo dei servizi è che i dettagli dell'implementazione possono essere modificati senza che i client debbano fare nulla. Da quello che hai descritto, sembra che non ci sia un vero livello di astrazione. I dettagli dell'implementazione sono stati esposti tramite HTTP. Nulla di REST dice che è necessario, utile o desiderabile. In effetti, penso che potrei discutere alcune parti della definizione REST per indicare che questa è in effetti un'implementazione non RESTful.

Quello che stai suggerendo è come dovrebbe essere progettato un adeguato livello di servizio. Se qualcuno ti sta dicendo che non puoi farlo perché non è RESTful, è sfortunato. Puoi essere certo che qualcuno che ti dice che sa poco o niente di REST.

In base alla tua domanda, hai una risorsa chiamata cliente. Qualsiasi cosa e tutto ciò che è necessario per creare una risorsa cliente valida può e deve essere gestita in POST alla risorsa base del cliente (o in alternativa / facoltativamente in PUT a una risorsa cliente specifica, se non esiste.) REST non dice nulla su quanti record di database è necessario creare su una determinata chiamata. Come ha commentato Colin Young, non è affatto necessario un database, è del tutto irrilevante il modo in cui i servizi vengono implementati da una prospettiva REST.

    
risposta data 21.06.2018 - 19:05
fonte
3

Ci sono alcune buone risposte qui, ma non sono sicuro che ti aiuteranno a convincere i tuoi colleghi. Come molti hanno sottolineato, ciò che stai suggerendo non è un allontanamento dal design RESTful, e penso che sia la chiave per farli salire a bordo con la tua proposta.

REST è non sull'assicurazione che la tua API consenta solo l'archiviazione e il recupero dei dati. Piuttosto, si occupa delle azioni di modellazione come . La tua API dovrebbe abilitare le azioni da intraprendere (dopotutto è un'interfaccia Programmazione ). La domanda è come modellare tali azioni.

Piuttosto che inventare un termine, gli esempi sono probabilmente il modo migliore per spiegare questo ai tuoi colleghi . In questo modo puoi mostrare come lo stanno facendo ora, quali problemi causa, una soluzione che risolve il problema e come rimane ancora RESTful.

Esaminiamo l'oggetto Cliente.

Problema:

I POST UI sono un cliente, ma le tabelle successive non sono ancora state aggiornate. Cosa succede se una delle chiamate successive fallisce a causa di un errore nel codice UI (o nel malfunzionamento del plug-in del browser, ecc.)? Ora i tuoi dati sono in uno stato incoerente. Potrebbe anche essere uno stato che rompe altre parti della tua API o dell'interfaccia utente, senza contare che è semplicemente non valido. Come si recupera? Dovresti testare per ogni possibile stato per essere sicuro che questo non romperebbe qualcosa, ma sarebbe difficile sapere cosa è possibile.

Soluzione:

Crea un endpoint API per creare clienti. Sai che non vuoi avere un endpoint "/ customer / create" o anche "/ create-customer", perché create è un verbo e violerebbe REST. Quindi lo si può dire. "/ creazione del cliente" potrebbe funzionare. Ora quando POST l'oggetto CustomerCreation, invierà tutti i campi necessari affinché un cliente possa essere completamente creato. L'endpoint assicurerà che i dati siano completi e validi (restituendo un 400 o qualcosa se fallisce la convalida), e potrebbero persistere tutti all'interno di una singola transazione db, per esempio.

Se hai bisogno di un endpoint per GET / oggetti cliente, va bene. Puoi avere entrambi. Il trucco è creare endpoint che soddisfino le esigenze dei consumatori.

Vantaggi:

  1. garantisci che non ti ritroverai con uno stato negativo
  2. In realtà è più facile sugli sviluppatori dell'interfaccia utente se non devono "sapere" l'ordine delle richieste, i problemi di convalida, ecc.
  3. Non è più come loquace di un'API, riducendo la latenza delle richieste di rete
  4. È più facile testare e concettualizzare gli scenari (frammenti di dati mancanti o malformati dall'interfaccia utente non sono distribuiti tra le richieste, alcuni dei quali potrebbero non riuscire)
  5. Consente un migliore incapsulamento della logica aziendale
  6. In genere rende la sicurezza più semplice (perché la logica di business e orchestrazione nell'interfaccia utente può essere modificata dagli utenti)
  7. Probabilmente ridurrà la duplicazione logica (più probabilmente avrai più di 2 utenti di un'API rispetto a 2+ API che danno accesso agli stessi dati)
  8. Ancora 100% RESTful

Svantaggi:

  1. È potenzialmente più utile per lo sviluppo del backend (ma potrebbe non essere a lungo termine)

Potrebbe essere difficile per le persone capire questo paradigma e ciò che è buono se non l'hanno provato. Spero che tu possa aiutarli a vedere usando un esempio dal tuo codice.

La mia esperienza è che una volta che gli sviluppatori del mio team hanno iniziato a implementare questa strategia, hanno visto quasi subito i vantaggi.

Ulteriore studio:

Questo articolo di thoughtworks mi ha davvero aiutato a ottenere l'idea di modellare le azioni come oggetti usando esempi pratici: link

Suggerirei anche di leggere su CQRS e Event Sourcing poiché riguardano proprio questo tipo di cose (cioè il divorzio dell'API dall'effettiva logica di persistenza). Non so quanto siano disposti i tuoi colleghi a leggere questo genere di cose, ma potrebbe darti più chiarezza e aiutarti a spiegarglielo.

    
risposta data 22.06.2018 - 16:47
fonte

Leggi altre domande sui tag