Devo convalidare l'output dell'API?

5

Sto lavorando su un'API Web per fornire dati a una terza parte in base alle specifiche fornite.

Il processo per ciascuna chiamata API è essenzialmente:
1. Estrarre i dati come XML 2. Deserializzare i dati in DTO (POCO)
3. Restituisci DTO come contenuto della risposta (che viene quindi serializzato su JSON tramite la negoziazione del contenuto Web API 2)

Mi è stato chiesto da qualcuno sul nostro team di sviluppo di convalidare i DTO.

Oltre a garantire che le risposte siano in un formato che il client può elaborare, che essenzialmente è stato già ottenuto creando le classi DTO, questo mi sembra uno spreco di energie. Ho controllato Google, ma l'unica validazione dell'output di cui si sta parlando è la disinfezione di valori come numeri di carte di credito e SSN. Non ricordo di aver mai visto un metodo convalidare un oggetto appena creato prima di restituirlo.

Poiché la risposta JSON è in realtà solo l'XML estratto dopo essere stato deserializzato e ricalibrato, l'unico modo in cui il DTO potrebbe essere non valido sarebbe se l'XML estratto non fosse valido. Quindi fondamentalmente testerei le estrazioni su ogni chiamata.

Tranne alcuni casi in cui è specificato il formato, in realtà non so quali valori sono considerati validi dal client. Il meglio che posso fare nella maggior parte dei casi è assicurarsi che non ci siano spazi vuoti. In sostanza, tenterei di ricreare ciecamente la convalida del client solo in modo da poter pre-validare i dati prima che il client lo confermasse comunque. Supponendo che sia riuscito a farlo bene, il risultato sarebbe stato quello di spostare l'onere di supporto iniziale per il nostro team perché il nostro server avrebbe lanciato eccezioni di convalida invece di il proprio client.

La struttura dei DTO è abbastanza complicata. Se ignoro il fatto che sono stati creati attraverso la deserializzazione, la convalida si complica rapidamente. La maggior parte dei problemi di convalida che dovrei verificare (ad esempio, elementi null array, valori vuoti) non sono effettivamente possibili nell'implementazione reale. XmlSerializer non creerà elementi di array nulli e i campi del database NOT NULL non determineranno la mancanza di elementi XML. Aggiungi la copertura del 100% del test unitario e questo sta aggiungendo un notevole sforzo e complessità.

La convalida dell'output è addirittura una pratica? Non l'ho mai visto prima. Sembra eccessivamente cauto e preventivo. Se è una pratica, c'è un altro termine che potrebbe aiutarmi a trovare maggiori informazioni sull'argomento?

    
posta user2097245 10.04.2015 - 02:59
fonte

2 risposte

4

I would essentially be attempting to blindly recreate the client's validation just so we could pre-validate the data before the client validated it anyway.

Dovendo farlo ciecamente dovrebbe essere una grande bandiera rossa che tu ei tuoi clienti non avete raggiunto un accordo su ciò che costituisce un dato valido. Se non sai come sono i dati validi, non puoi testare il tuo codice. Se non riesci a testare il tuo codice, non puoi dire che funzioni con qualsiasi livello di confidenza. In sostanza, stai dipendendo dai tuoi clienti per trovare i tuoi bug, il che non va bene.

Is output validation even a practice?

Assolutamente. Indipendentemente dal fatto che sia una pratica abbastanza comune è aperta al dibattito. : -)

La convalida dell'output fa parte di qualcosa chiamato design per contratto (o DbC ), che è un termine coniato da Bertrand Meyer quando ha progettato il linguaggio di programmazione Eiffel negli anni '80. Uno dei principi di progettazione che circonda DbC stabilisce che il primo passo nello sviluppo di un'unità di codice è specificare quali condizioni devono essere soddisfatte in ingresso ( precondizioni ) e exit ( postconditions ) per esecuzione da considerare riuscita. Queste condizioni, chiamate contratto , sono strumenti estremamente potenti per garantire che tutte le parti capiscano che cosa si suppone che il codice debba fare e che sia in grado di mantenere quelle promesse. Il link qui sopra contiene una descrizione più dettagliata dei contratti e perché li vorresti. Eiffel e una manciata di altri linguaggi supportano DbC o qualcosa del genere direttamente; molti altri lo fanno con asserzioni o pacchetti aggiuntivi.

Ciò che stai generando sembra abbastanza complesso da dover utilizzare una o più funzioni per generare ciascuna parte. Quando suddividi l'intero in parti più piccole, specificando ciò che è corretto per ogni pezzo e facendo la verifica diventa un insieme di attività più piccole e più semplici che sono meno inclini agli errori.

Ad esempio, supponiamo che la parte A del tuo output sia composta da sub-parti B , C e D . Se le funzioni che generano B , C e D possono garantire che i loro output siano corretti, la convalida di A diventa una semplice questione di verificare che gli altri tre abbiano effettivamente prodotto qualcosa. Se non ci sono convalide nella generazione delle sotto-parti, tocca a A controllare tutto e questo può diventare molto complesso molto rapidamente.

Se questo sembra una duplicazione degli sforzi già compiuti dal cliente, non dovrebbe esserlo. In un mondo ideale, la classe che rappresenta B avrebbe caratteristiche per garantire che gli input e gli output fossero validi e l'implementazione sarebbe utilizzata ad entrambe le estremità della transazione. Quando ciò non è possibile, il meglio che può accadere è che entrambe le parti fanno la propria convalida. Questo ostacolo è di solito amministrativo piuttosto che tecnico. In ogni caso, non c'è niente di sbagliato nella validazione extra: lo stai facendo per assicurarti che ciò che produci sia corretto e il client faccia la sua versione per rilevare i tuoi errori.

    
risposta data 10.04.2015 - 15:25
fonte
2

Questa è una domanda interessante e sono quasi esattamente nella stessa situazione al momento.

Sono giunto alla conclusione che è in realtà abbastanza necessario perché è del tutto possibile che tu possa rinominare un campo nel tuo DTO. Cosa succede allora? Correggi il resto del tuo codice, fai funzionare tutto, distribuisci il tuo nuovo servizio web, ma ora il tuo cliente si lamenta che il tuo XML non è corretto. Tutto funziona sulla tua parte ma non hai rilevato l'errore.

Il mio servizio web restituisce JSON, ma è lo stesso principio. Ho un test unitario che crea un'istanza del controller WebApi, chiama il metodo e recupera il risultato come JSON e si assicura che il risultato sia corretto. Se prendi in giro e stub i tuoi dati, puoi assicurarti che l'intero risultato restituito sia esattamente come ti aspetti. Ricordare che non si sta testando il codice di serializzazione WebApi di .NET, non si sta verificando che i valori di output siano corretti, si sta verificando che l'output del proprio servizio Web sia sintatticamente corretto (i campi XML sono nidificati correttamente e denominati correttamente) .

Direi che con XML è altrettanto probabile (probabilmente più probabile) che potresti cambiare accidentalmente il formato senza nemmeno accorgertene e interrompere il servizio per i tuoi client. Quindi sì, provaci, convalida.

    
risposta data 10.04.2015 - 03:16
fonte

Leggi altre domande sui tag