perché le persone eseguono le API REST anziché le DBAL?


32

Nelle ultime due società sono stato alle API REST per interrogare i dati tramite un'app Web. vale a dire. invece di fare in modo che l'app Web esegua direttamente SQL, chiama un'API REST, che esegue l'SQL e restituisce il risultato.

La mia domanda è ... perché è fatto?

Se fosse stato esposto a terzi, avrei capito. Meglio esporre un'API REST limitata rispetto al DB completo. Ma in entrambe queste società non è così.

Mi è stato suggerito che queste API REST rendono più semplice il passaggio da un DBMS all'altro. Ma non è questo il punto di un livello di astrazione del database (DBAL)? Forse usi un ORM come DBAL o potresti semplicemente scrivere SQL grezzo e fare in modo che il tuo DBAL traduca le cose specifiche del DB, se appropriato (ad esempio, traduci LIMIT per MySQL in TOP per MSSQL).

Ad ogni modo mi sembra superfluo. E penso che renda anche più difficile la diagnosi dei problemi. Se un report sull'app Web sta fornendo i numeri errati, non puoi semplicemente scaricare la query SQL: devi scaricare l'URL REST e poi entrare nel progetto che funge da API REST ed estrarre l'SQL da quello. Quindi è un ulteriore livello di riferimento indiretto che rallenta il processo diagnostico.


3
Sembra che tu abbia lavorato solo con app fondamentalmente CRUD: alcuni utenti inseriscono dati con moduli e altri utenti leggono i dati con gli stessi moduli o con stampe di report? Se non hai mai lavorato con un sistema che ha bisogno di un modello di dominio complesso e sofisticato, allora posso vedere come avresti quella particolare mentalità. Molte applicazioni richiedono quel livello extra di riferimento indiretto per fare cose.
RibaldEddie,

1
Ho lavorato con le API (non necessariamente REST) ​​che (tra le altre cose) hanno eseguito calcoli sui parametri che le sono stati passati. Forse un DBMS viene utilizzato in quei calcoli ma presumibilmente gran parte della logica non vive nel DB. Tuttavia, le API interne delle aziende in cui ho lavorato non lo fanno. Interrogano semplicemente un DBMS e sputano i risultati della query SQL alla lettera. Mi sembra solo che le API REST siano spesso (non sempre - spesso) scritte per essere alla moda - non per essere pratiche.
neubert

1
Ci sono sicuramente stranezze nella progettazione dell'API REST che rendono difficile progettare bene un dominio complesso: la maggior parte degli sviluppatori che ho incontrato negli anni non si preoccupano della progettazione. Vogliono sfornare il codice il più velocemente possibile in modo che i loro capi li adorino e pensino che siano rockstar. Quando combini questo fatto con una tendenza come REST, ottieni API spaghetti alla moda ma poco pratiche. Non ha nulla a che fare con REST stesso.
RibaldEddie,

3
vi siete mai chiesti come alcune compagnie web riferiscano che i loro interi record di utenti sono stati rubati da un hacker? Vi siete mai chiesti come l'ha fatto l'hacker? Quando pensi che un server web abbia una connessione diretta con il DB, ti rendi conto che una volta che il web server è stato violato, l'attaccante ha accesso completo e senza restrizioni per selezionare qualsiasi cosa dal DB che gli piace. Attaccalo dietro un livello intermedio e l'attaccante può quindi chiamare solo metodi sul livello intermedio. Non dirò che è la sicurezza istantanea, ma è significativamente migliore.
gbjbaanb,

1
@gbjbaanb: Il mio punto è che il server web può accedere ai dati attraverso il server di riposo, quindi se il server web viene hackerato, l'attaccante può anche accedere ai dati attraverso il server di riposo senza dover hackerare il server di riposo.
Jacques B

Risposte:


28

Se si consente a un client di accedere direttamente al database, cosa che farebbe, anche con un livello di astrazione del database, allora:

  • Ottieni un accoppiamento tra il loro codice e il tuo - in particolare, esiste un accoppiamento molto forte tra la struttura del tuo database e il loro codice;
  • Il tuo client potrebbe fare cose piuttosto indesiderabili nel tuo database - sia che si tratti di aggiornare i dati che non dovrebbero, scrivere una query che impiega troppo tempo, bloccare deadlock perché non acquisiscono i blocchi in modo pulito ...
  • Se hai fatto una scelta non ottimale nella struttura del tuo database, spostarti da quella scelta può essere molto difficile, specialmente se non hai un buon modo per far migrare i tuoi clienti verso nuove strutture.

Cioè, non sto affatto toccando la parte REST: isolare il database dietro un'API è semplicemente una scelta più sensata se il team che gestisce il database e i team che lo utilizzano non sono sincronizzati, poiché consente a queste parti di evolversi al proprio ritmo.


24

Hai ragione, non è evidente il vantaggio di introdurre un livello API REST tra un'app Web e un database e ha un costo in termini di complessità e costi generali.

Il motivo per cui stai ottenendo risposte contraddittorie è la confusione su ciò che è il "cliente" nella tua architettura.

Nella tua architettura (se ho capito bene), hai browser che interagiscono con una singola app Web, che a sua volta interagisce con il database. L'introduzione di un livello API REST tra l'app Web e il database non ha alcun vantaggio. Tutti i vantaggi dichiarati (memorizzazione nella cache, isolamento del database ecc.) Possono essere raggiunti con i livelli di accesso ai dati nel codice.

Ma ci sono altre architetture in cui un'API REST ha senso:

  • Se si dispone di più client che accedono al database, ovvero non una singola app Web ma più app Web indipendenti che accedono allo stesso database. Potrebbe essere utile creare un'interfaccia REST comune per consentire la condivisione del modello di dati, la memorizzazione nella cache, ecc. Sicuro che puoi ottenere alcuni dei vantaggi condividendo le stesse librerie DAL, ma che non funzioneranno se le app sono sviluppate in lingue diverse e su differenti piattaforme. Questo è comune nei sistemi aziendali.

  • Se si dispone di più app desktop che accedono direttamente al database. Questa è la classica architettura "a due livelli", che è caduta in disgrazia rispetto alle app web. L'introduzione di un livello REST consente di centralizzare la logica di accesso ai dati e in particolare consente un controllo più rigoroso della sicurezza, poiché è rischioso avere più client distribuiti che accedono direttamente allo stesso database.

  • Se hai un codice JavaScript che recupera direttamente i dati dal server, allora hai bisogno di qualcosa come un'API REST.


1
Mi è piaciuta la tua risposta ma ho qualche altra domanda che ne deriva. Ti piace la perdita di prestazioni con l'introduzione di un altro livello di astrazione? Inoltre, non lo rende unico punto di errore (se questo va giù tutto il resto va giù) e possibili colli di bottiglia (ogni app in attesa di connessione DB dal pool)?
Sactiw,

@satich: non capisco esattamente cosa stai chiedendo, puoi essere più specifico? Stai chiedendo un singolo punto di errore con o senza un livello REST?
Jacques

Il livello aggiuntivo può essere utile se si dispone di più di un'app che comunica con essa
Ewan,

@Ewan: Sì, questo è quello che dichiaro nel primo punto elenco.
Jacques

1
@JacquesB Supponiamo che più app Web condividano lo stesso DB ma non gli stessi dati, ad esempio ciascuno che esegua operazioni CRUD su un set separato di dati all'interno di quel DB, in pratica non esiste una condivisione dei dati in senso reale. Quindi mettere le app dietro un framework di persistenza Restful ha senso (supponiamo anche che DB fornisca un buon livello di concorrenza nelle query)? Inoltre, tale framework non costituirà un collo di bottiglia e un singolo punto di errore per così tante app Web che interagiscono tramite esso?
sacro il

12

Attenzione: grande post, alcune opinioni, vaga conclusione "fai ciò che funziona meglio per te"

Generalmente, ciò viene fatto come mezzo per implementare "architettura esagonale" attorno al database. Puoi avere applicazioni web, applicazioni mobili, applicazioni desktop, importatori di massa ed elaborazione in background che consumano il tuo database in modo uniforme. Certamente potresti ottenere la stessa cosa in una certa misura scrivendo una ricca libreria per accedere al tuo database e facendo in modo che tutti i tuoi processi utilizzino quella libreria. E in effetti, se sei in un piccolo negozio con un sistema molto semplice, è probabilmente una strada migliore da percorrere; È un approccio più semplice e se non hai bisogno delle funzionalità avanzate di un sistema più complicato, perché pagare per la complessità? Tuttavia, se stai lavorando con un insieme ampio e sofisticato di sistemi che devono tutti interagire con il tuo database su larga scala, lì "

Indipendenza e manutenzione della piattaforma

Se si dispone di un database e si scrive una libreria Python per interagire con quel database e tutti inseriscono quella libreria per interagire con il database, è fantastico. Ma diciamo improvvisamente che devi scrivere un'app mobile e che ora l'app mobile deve parlare anche con il database. E i tuoi ingegneri iOS non usano Python, e i tuoi ingegneri Android non usano Python. Forse i ragazzi iOS vogliono usare le lingue di Apple e gli ingegneri Android vogliono usare Java. Quindi rimarrai bloccato a scrivere e gestire la tua libreria di accesso ai dati in 3 lingue diverse. Forse gli sviluppatori iOS e Android decidono di usare qualcosa come Xamarin per massimizzare il codice che possono condividere. Perfetto, tranne che probabilmente dovrai ancora trasferire la tua libreria di accesso ai dati su .NET. E poi la tua azienda ha appena acquistato un'altra società che " L'applicazione Web è un prodotto disparato ma correlato e l'azienda desidera integrare alcuni dei dati dalla piattaforma della propria azienda nella piattaforma della filiale appena acquisita. C'è solo un problema: la filiale era una start-up e ha deciso di scrivere la maggior parte della sua applicazione in Dart. Inoltre, per qualsiasi motivo (ragioni probabilmente al di fuori del tuo controllo) il team mobile che stava pilotando Xamarin ha deciso che non faceva per loro e che avrebbero preferito usare gli strumenti e le lingue specifici dei dispositivi mobili per i quali svilupperanno. Ma mentre eri in quella fase, il tuo team aveva già distribuito gran parte della tua libreria di accesso ai dati in .NET, e un altro team della società stava scrivendo alcune cose folli sull'integrazione di Salesforce e ha deciso di fare tutto ciò in .NET da lì era già una libreria di accesso ai dati per.

Quindi ora, a causa di una svolta molto realistica degli eventi, hai la tua libreria di accesso ai dati scritta in Python, .NET, Swift, Java e Dart. Non sono neanche belli come vorresti che fossero. Non puoi usare un ORM nel modo più efficace che desideri, perché ogni lingua ha strumenti ORM diversi, quindi hai dovuto scrivere più codice di quanto ti sarebbe piaciuto. E non sei stato in grado di dedicare tanto tempo a ciascuna incarnazione come avresti voluto, perché ce ne sono 5. E la versione Dart della libreria è particolarmente pelosa perché per alcuni di essi è stato necessario creare il proprio materiale transazionale perché le librerie e il supporto non erano proprio lì. Hai provato a sostenere che, a causa di ciò, l'applicazione Dart avrebbe dovuto avere solo funzionalità di sola lettura per il tuo database, ma l'azienda aveva già deciso che qualunque caratteristica stessero pianificando valeva lo sforzo extra. E si scopre che c'è un bug in alcune delle logiche di validazione che esistono in tutte queste incarnazioni della tua libreria di accesso ai dati. Ora devi scrivere test e codice per correggere questo errore in tutte queste librerie, ottenere revisioni del codice per le modifiche apportate a tutte queste librerie, ottenere QA su tutte queste librerie e rilasciare le modifiche a tutti i sistemi utilizzando tutti i queste biblioteche. Nel frattempo, i tuoi clienti sono scontenti e si sono rivolti a Twitter, mettendo insieme combinazioni di volgarità che non avresti mai immaginato possano essere concepite, per non parlare del prodotto di punta della tua azienda. E il proprietario del prodotto decide di non capire bene la situazione.

Si prega di comprendere che in alcuni ambienti, l'esempio sopra è tutt'altro che inventato. Considera anche che questa sequenza di eventi potrebbe svolgersi nel corso di pochi anni. Generalmente, quando arrivi al punto in cui architetti e uomini d'affari iniziano a parlare di collegare altri sistemi al tuo database, è allora che vorrai "mettere un'API REST davanti al database" nella tua tabella di marcia. Considerare se all'inizio, quando era chiaro che questo database stava per iniziare a essere condiviso da alcuni sistemi, un servizio web / API REST è stato messo di fronte ad esso. Correggere il tuo bug di validazione sarebbe molto più semplice e veloce perché lo stai facendo una volta invece di 5 volte. Rilasciare la correzione sarebbe molto più facile da coordinare, perché

TLDR; È più semplice centralizzare la logica di accesso ai dati e mantenere client HTTP molto sottili piuttosto che distribuire la logica di accesso ai dati a ciascuna applicazione che deve accedere ai dati. In effetti, il tuo client HTTP potrebbe persino essere generato da metadati. Nei sistemi di grandi dimensioni, l'API REST consente di mantenere meno codice

Prestazioni e scalabilità

Alcune persone potrebbero credere che parlare direttamente con il database invece di passare prima attraverso un servizio web sia più veloce. Se hai una sola applicazione, è certamente vero. Ma nei sistemi più grandi, non sono d'accordo con il sentimento. Alla fine, a un certo livello di scala, sarà molto utile mettere un qualche tipo di cache davanti al database. Forse stai usando Hibernate e vuoi installare una griglia Infinispan come cache L2. Se hai un cluster di 4 server robusti per ospitare il tuo servizio web separato dalle tue applicazioni, puoi permetterti di avere una topologia integrata con la replica sincrona attivata. Se provi a inserirlo in un cluster di 30 server applicazioni, il sovraccarico di attivare la replica in quella configurazione sarà troppo, quindi " O dovrò eseguire Infinispan in una modalità distribuita o in una sorta di topologia dedicata, e improvvisamente Hibernate deve uscire dalla rete per poter leggere dalla cache. Inoltre, Infinispan funziona solo in Java. Se hai altre lingue, avrai bisogno di altre soluzioni di memorizzazione nella cache. Il sovraccarico della rete di dover passare dall'applicazione al servizio Web prima di raggiungere il database è rapidamente compensato dalla necessità di utilizzare soluzioni di cache molto più complicate che generalmente vengono fornite con un sovraccarico.

Inoltre, quel livello HTTP dell'API REST fornisce un altro prezioso meccanismo di memorizzazione nella cache. I server per l'API REST possono mettere le intestazioni di memorizzazione nella cache sulle loro risposte e queste risposte possono essere memorizzate nella cache a livello di rete, che si adatta in modo eccezionalmente buono. In una configurazione di piccole dimensioni, con uno o due server, la soluzione migliore è utilizzare una cache di memoria nell'applicazione quando si parla al database, ma in una piattaforma di grandi dimensioni con molte applicazioni in esecuzione su molti server, si desidera sfruttare il rete per gestire la memorizzazione nella cache, perché quando configurato correttamente qualcosa come calamari o vernici o nginx può ridimensionarsi a livelli folli su hardware relativamente piccolo. Centinaia di migliaia o milioni di richieste al secondo di throughput sono molto più economiche da eseguire da una cache HTTP che da un server delle applicazioni o di un database.

Inoltre, avere un sacco di client tutti puntati sul tuo database, invece di averli tutti puntati su alcuni server che a loro volta puntano sul database, può rendere molto più difficile l'ottimizzazione del database e del pool di connessioni. In generale, la maggior parte del carico di lavoro effettivo su un server delle applicazioni è roba dell'applicazione; attendere che i dati tornino dal database richiede spesso tempo, ma generalmente non è molto costoso dal punto di vista computazionale. Potrebbero essere necessari 40 server per gestire il carico di lavoro dell'applicazione, ma probabilmente non sono necessari 40 server per orchestrare il recupero dei dati dal database. Se si dedica tale attività a un servizio Web, il servizio Web sarà probabilmente in esecuzione su molti meno server rispetto al resto dell'applicazione, il che significa che saranno necessarie molte meno connessioni al database. Il che è importante perché i database generalmente non

TLDR; È più facile ottimizzare, ridimensionare e memorizzare nella cache l'accesso ai dati quando si verifica qualcosa all'interno di un singolo servizio Web dedicato rispetto a quando accade in molte applicazioni diverse utilizzando lingue e tecnologie diverse

Pensieri finali

Per favore, non allontanarti da questo pensiero "Oh wow, dovrei sempre usare le API REST per ottenere i miei dati" o "Questo idiota sta cercando di dire che stiamo sbagliando perché la nostra app web parla direttamente al database, ma la nostra roba funziona benissimo! " . Il punto principale che sto cercando di sottolineare è che sistemi diversi e aziende diverse hanno requisiti diversi; In molti casi, mettere un'API REST davanti al tuo database non ha davvero senso. È un'architettura più complicata che richiede di giustificare quella complessità. Ma quando la complessità è garantita, ci sono molti vantaggi nell'avere l'API REST. Essere in grado di soppesare le diverse preoccupazioni e scegliere l'approccio giusto per il tuo sistema è ciò che rende un buon ingegnere.

Inoltre, se l'API REST sta ostacolando il debug delle cose, probabilmente c'è qualcosa di sbagliato o mancante in quell'immagine. Non credo che avere quel livello di astrazione aggiunto intrinsecamente renda più difficile il debug. Quando lavoro con grandi sistemi di livello n, mi piace assicurarmi di avere un contesto di registrazione distribuito. Forse quando un utente avvia una richiesta, genera un GUID per quella richiesta e registra il nome utente dell'utente e la richiesta che ha effettuato. Quindi, passa quel GUID mentre l'applicazione comunica con altri sistemi. Con un'adeguata aggregazione e indicizzazione dei registri, è possibile eseguire una query dell'intera piattaforma per l'utente che segnala il problema e avere visibilità su tutte le loro azioni e scorrere attraverso il sistema per identificare rapidamente dove sono andate le cose. Ancora una volta, è un'architettura più complicata,

Fonti: http://alistair.cockburn.us/Hexagonal+architecture https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing


Ottima risposta, vale la pena leggere. Grazie per aver dedicato del tempo a scrivere questa grande risposta!
Dominic,

6

Se capisco correttamente cos'è un DBAL , la risposta è che un'interfaccia REST ti consente di utilizzare qualsiasi lingua per i suoi client, mentre un DBAL è una libreria che ti consente di utilizzare una sola lingua per i suoi client.

Questo, a sua volta, può essere un vantaggio per un'azienda in cui vi sono molti team di sviluppo e non tutti sono competenti nella stessa lingua. Consentire ai loro software di interrogare direttamente il DB sarebbe equivalente in termini di funzionalità, ma come dici "meglio esporre un'API REST limitata rispetto al DB completo".

In termini più astratti, tu stesso stai rispondendo alla domanda:

Quindi è un ulteriore livello di riferimento indiretto che rallenta il processo diagnostico

... dato che esiste questo famoso aforisma che afferma: "Tutti i problemi nell'informatica possono essere risolti da un altro livello di riferimento indiretto". :)


6

Solo perché sei all'interno della stessa azienda non significa che dovresti esporre tutto a tutti. Le API REST sono un modo per definire una relazione consumatore / fornitore limitata tra i team di un'azienda, con un contratto chiaro. Amazon è stato un pioniere in questa forma di organizzazione.

Le API forniscono anche un livello di astrazione, che consente di utilizzare un insieme specifico di idiomi: non si desidera necessariamente parlare con i propri consumatori negli stessi termini utilizzati nel database. Inoltre, non devi necessariamente parlare con ogni consumatore allo stesso modo.


3

Stai pensando che REST è per le query del database e non lo è. REST rappresenta lo stato di qualcosa al momento. L'uso di REST modifica o recupera una rappresentazione ma questo è tutto. Se quello stato diventa disponibile dal database, non importa e nessuno se ne preoccupa perché COME quella rappresentazione diventa non fa parte di REST e nemmeno le query del database.


Non sto suggerendo che le query del database == REST. Certamente REST è in grado di essere molto più di un livello di astrazione di database, ma in passato due società per cui ho lavorato è essenzialmente tutto ciò che è: un livello di astrazione di database. Non fa altro che tradurre le richieste HTTP in query DB. E se è tutto ciò che stai facendo, mi sembra che saresti meglio servito da DBAL. In effetti, mi sembra che l'unica ragione per cui alcune persone stanno usando REST al giorno d'oggi è perché è alla moda, non perché è la migliore soluzione là fuori per il compito da svolgere.
neubert

@neubert DBAL funziona direttamente su Internet come REST?
Rob

Sicuro. Puoi dire a MySQL di utilizzare un indirizzo IP / nome dominio / porta che appartiene a un altro computer su Internet. Puoi usare il tunneling SSH e l'autenticazione SSL (credo). Presumibilmente altri DBMS funzionano in modo simile.
neubert

@neubert: in quel caso, l'API REST è un DBAL, no?
Remco Gerlich,

2
@RemcoGerlich - certo, ma l'utilizzo dell'API REST come DBAL potrebbe aggiungere un livello intermedio che non è necessario e ostacola la diagnosi dei problemi. Voglio dire, se utilizzerai una definizione sufficientemente ampia di DBAL, potresti considerare i SERP di Google come DBAL. Devi solo analizzare l'HTML per ottenere i dati impaginati dai server di Google ...
Neubert,
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.