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


37

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

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

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


44
Limitare le tue API a CRUD richiede di renderlo "RESTful" è uno scarso compromesso.
Robert Harvey,

38
@EsbenSkovPedersen: Best Friend Forever?
Robert Harvey,

5
Invece di preoccuparmi se il tuo servizio è conforme a REST (iirc, quasi nessuno lo fa), mi preoccuperei di più della conformità alle specifiche HTTP . Anche la maggior parte delle API con cui ho lavorato non è conforme alle specifiche, ma è un obiettivo più realizzabile e utile.
aaaaaa,

7
@aaaaaa, la ragione per cui quasi nessun servizio è conforme al REST è che nessuno può decidere quale sia il REST. L'unico punto di accordo che ho trovato è "tutti gli altri stanno sbagliando".
Segna il

16
- "Come descrivere un cambiamento architettonico che infrange intenzionalmente gli standard REST?" - disRESTpect . ( Ci scusiamo per un commento non professionale, è stato più forte di me. )
luk32

Risposte:


49

Non sono sicuro di come descrivere al meglio questo approccio quando la mia raccomandazione è di continuare con lo stack tecnologico esistente, ma implementare cambiamenti fondamentali nelle posizioni in cui il codice appartiene.

Service oriented architecture.

Stai proponendo di ridisegnare il tuo sistema in modo che le tue regole aziendali e i tuoi dati siano nello stesso posto. Questa è effettivamente la definizione di un servizio ; vedere il discorso di Udi Dahan sulla ricerca dei confini del servizio .

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

Può o meno valere la pena investire nel cambiare la comprensione del REST da parte del pubblico.


32
Né può valere la pena investire in REST. Se leggi la tesi di Roy Fielding (o come ho spiegato REST a mia moglie ), il vero scopo di REST è fornire una rappresentazione canonica per le risorse su Internet, in modo che macchine disparate su Internet avrebbero un modo standard di manipolare tali risorse . Un'applicazione di proprietà privata potrebbe non aver nemmeno bisogno di questa funzionalità.
Robert Harvey,

29

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


6
Beh, no, non è una mappatura perfetta per CRUD, ma cammina e parla e canta in modo molto simile a CRUD, almeno nel modo in cui la maggior parte delle persone lo interpreta.
Robert Harvey,

11
@RobertHarvey Penso che sia la (cattiva) comprensione che è il problema qui.
JimmyJames,

4
@JimmyJames: è un malinteso pervasivo. C'è una forte spinta a rendere le cose "riposanti" quando la maggior parte delle persone non capisce nemmeno quali siano i benefici o come tali benefici si applicherebbero a loro.
Robert Harvey,

4
@RobertHarvey Penso che tu stia dicendo che se farlo nel modo sbagliato è REST, allora REST non dovrebbe essere un obiettivo. OK, ma per come la vedo io, chiamare questo "non RESTO" è una cazzata e io sono un grande sostenitore di chiamare cazzate sulle cazzate. Le parole hanno bisogno di un significato comunemente compreso per essere utili.
JimmyJames,

5
@RobertHarvey Concesso, ma ciò non accadrà fintanto che ci saranno abbastanza persone disposte a correggere questi abusi del termine. Non sono pronto a gettare la spugna.
JimmyJames,

24

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

Ciò significa che, ad esempio, mentre l'applicazione angolare potrebbe verificare se il cliente ha una fascia di età valida e garantire che gli utenti legittimi ottengano il feedback corretto, chiunque conosca l'URL per l'API può fare una richiesta POST contenente alcuni valori non legittimi che potrebbero non essere più convalidato.

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


5
Questa è di gran lunga la risposta più utile qui: l'API è la superficie di attacco, non l'input per il client. Qualsiasi richiesta API può essere falsificata. Pertanto, tutto ciò che può essere fatto con l'API pura è ciò che può fare un kiddie di script senza talento e malizioso. Il software client può essere utilizzato per fornire un'esperienza utente migliore, ma è il server che deve applicare le regole.
cmaster

10

Per aggiungere alle altre buone risposte qui:

L'interfaccia, REST o altro, non dovrebbe essere vincolata sulla base di una sorta di ipotesi sui dettagli dell'implementazione. Ciò è completamente antitetico alla nozione di servizi come strato di astrazione.

Uno dei principali vantaggi dell'utilizzo dei servizi è che i dettagli di 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 di poter argomentare alcune parti della definizione REST per significare che si tratta in realtà di un'implementazione non RESTful.

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

Sulla base della tua domanda, hai una risorsa chiamata cliente. Tutto e tutto ciò che è necessario per creare una risorsa cliente valida può e deve essere gestito in una POSTrisorsa della base clienti (o in alternativa / facoltativamente in un PUT a una risorsa cliente specifica, se non esiste.) REST non dice nulla su quante record del database che è necessario creare in una determinata chiamata. Come ha commentato Colin Young, non è necessario disporre di un database, è del tutto irrilevante il modo in cui i servizi vengono implementati dal punto di vista REST.


3
REST non dice nulla sui record del database, figuriamoci quanti. Potrei creare un servizio REST che controllava una valvola dell'acqua ed esponeva una valvola dell'acqua, l'approvvigionamento idrico e le risorse a livello del serbatoio. Si potrebbe sostenere che gli oggetti fisici stessi siano un "database" ma che allunga un po 'le cose.
Colin Young,

@ColinYoung Sì, grazie per l'aiuto nel chiarire.
JimmyJames,

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 passaggio dal design RESTful e penso che sia la chiave per farli aderire alla tua proposta.

REST non si assicura che l'API consenta solo di archiviare e recuperare dati. Piuttosto, si occupa di modellare le azioni come risorse. L'API dovrebbe consentire di intraprendere azioni ( dopotutto è un'interfaccia di programmazione dell'applicazione ). La domanda è come modellare quelle azioni.

Invece di trovare un termine, gli esempi sono probabilmente il modo migliore per spiegarlo ai tuoi colleghi . In questo modo puoi mostrare come lo stanno facendo ora, quali problemi provoca, una soluzione che risolve il problema e come rimane RESTful.

Diamo un'occhiata al tuo oggetto Cliente.

Problema:

L'interfaccia utente invia un cliente, ma le tabelle successive non sono ancora state aggiornate. Cosa succede se una delle chiamate successive non riesce a causa di un errore nel codice dell'interfaccia utente (o di un plugin del browser che si comporta male, ecc.)? Ora i tuoi dati sono in uno stato incoerente. Potrebbe anche essere uno stato che rompe altre parti dell'API o dell'interfaccia utente, per non parlare del fatto che non è semplicemente valido. Come ti riprendi? Dovresti testare ogni stato possibile per essere sicuro che ciò non rompa 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 "/ create-customer", perché create è un verbo e violerebbe REST. Quindi nominalo. "/ customer-creation" potrebbe funzionare. Ora quando POST l'oggetto CustomerCreation, invierà tutti i campi necessari per la creazione completa di un cliente. L'endpoint garantirà che i dati siano completi e validi (restituendo un valore di 400 o qualcosa del genere se fallisce la convalida) e, ad esempio, potrebbe persistere all'interno di una singola transazione db.

Se hai anche 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 finirai con un cattivo stato
  2. In realtà è più facile per gli sviluppatori dell'interfaccia utente se non devono "conoscere" l'ordine delle richieste, i problemi di convalida, ecc
  3. Non è loquace di un'API, riducendo la latenza delle richieste di rete
  4. È più facile testare e concettualizzare gli scenari (parti mancanti / non corrette dell'interfaccia utente non sono distribuite tra le richieste, alcune delle quali potrebbero non riuscire)
  5. Consente una migliore incapsulamento della logica aziendale
  6. In genere semplifica la sicurezza (poiché la logica aziendale e di orchestrazione nell'interfaccia utente può essere modificata dagli utenti)
  7. Ridurrà probabilmente la duplicazione della logica (più probabilmente avrai 2+ utenti di un'API rispetto alle 2+ API che danno accesso agli stessi dati)
  8. Ancora al 100% RESTful

svantaggi:

  1. È potenzialmente più lavoro per lo sviluppatore back-end (ma potrebbe non essere a lungo termine)

Potrebbe essere difficile per le persone comprendere questo paradigma e cosa c'è di buono se non lo hanno provato. Spero che tu possa aiutarli a vedere usando un esempio dal tuo codice.

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

Ulteriore studio:

Questo articolo di Thoughworks mi ha davvero aiutato ad avere l'idea di modellare le azioni come oggetti usando esempi pratici: https://www.thoughtworks.com/insights/blog/rest-api-design-resource-modeling

Vorrei anche suggerire di leggere su CQRS e Event Sourcing in quanto si occupano proprio di questo tipo di cose (cioè separare l'API dall'attuale logica di persistenza). Non so quanto sarebbero disposti i tuoi colleghi a leggere questo genere di cose, ma potrebbe darti più chiarezza e aiutarti a spiegarglielo.


" Perché creare è un verbo e violerebbe REST " - Assolutamente corretto. In altre parole, sarebbe quindi l'approccio 47.258.346 per eseguire " RPC su REST ". Il che è qualcosa che attribuirei almeno "innaturale", perché abusa e travisa gli approcci RESTful (hanno i loro casi d'uso, ma RPC non è uno di loro) e tende anche ad essere inefficiente.
JensG,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.