Come gestire gli URI contenenti parametri non utilizzati dall'API?

7

In un'interfaccia API REST, dovrei verificare esplicitamente che il client abbia utilizzato solo i parametri utilizzati dall'API e restituire un HTTP 403 se un parametro di cui l'API non è a conoscenza era incluso nella richiesta?

Un po 'di contesto. Sto lavorando su un'API che minimizza i file JavaScript e LESS. Originariamente, i file JavaScript sono stati minimizzati utilizzando Google Closure Compiler. Poiché Closure Compiler ha più livelli di ottimizzazione (solo spazi bianchi, semplici ottimizzazioni e ottimizzazioni avanzate), l'API ha anche permesso al chiamante di specificare (facoltativamente) il livello, quindi:

POST http://example.com/api/v1/js?level=whitespace

e

POST http://example.com/api/v1/js?level=advanced

nella maggior parte dei casi darebbe risultati diversi.

Recentemente, ho dovuto aggiungere il supporto per ES6. Data la mancanza di un adeguato supporto per ES6 da parte di Closure Compiler, ho aggiunto YUI Compressor. Poiché questo non ha livelli di ottimizzazione, la chiamata ora è semplicemente:

POST http://example.com/api/v1/es6

Dopo POLA , ho l'impressione che non possa consentire ai chiamanti di utilizzare l'API in questo modo:

POST http://example.com/api/v1/es6?level=advanced

perché si aspetterebbero un risultato specifico, ma ne ottengono uno diverso. La soluzione consisterebbe nel verificare la presenza del parametro level nell'URI e restituire un messaggio di errore che indica che il parametro non è supportato.

Ma controllo questo parametro specifico, perché non verifichi la presenza di lecel (un errore di battitura), o optimize (a ipotesi), o altro?

Pertanto, l'API si aspetta che i parametri a , b e c siano eventualmente inclusi nell'URI, quale dovrebbe essere la risposta se l'URI contiene anche d o e ?

    
posta Arseni Mourzenko 29.12.2017 - 16:39
fonte

4 risposte

2

Direi che il tuo approccio attuale è quello che segue il principio del minimo stupore.

RESTfully parlando, hai definito due diverse risorse sotto v1: js ed es6. Non c'è motivo per cui questi dovrebbero accettare gli stessi parametri di query, che aiutano nella rappresentazione della risorsa.

Eppure, stai pensando che, poiché tutti questi sono minimizzatori js, accettano gli stessi parametri. E in realtà non è una sorpresa che diversi minimizzatori richiederanno parametri diversi.

Un'altra considerazione è che i consumatori di API sono molto ben abituati a percorsi diversi che richiedono parametri diversi, di solito non hanno la trasparenza di cambiare le risorse e di mantenere gli stessi parametri. L'eccezione a questa regola potrebbe essere un parametro di autenticazione o un parametro di impaginazione per la maggior parte delle API, ma questa è un'eccezione perché si occupa di problemi trasversali che sono responsabilità a livello di applicazione.

Nel tuo caso, nessuno di questi si applica direttamente. Penso che il tuo attuale design sia quello che sembra più naturale e stupisce di meno.

    
risposta data 04.01.2018 - 12:41
fonte
3

Dato che hai già la versione per l'API (ovvero, nessun problema di compatibilità a ritroso / inoltro), sarebbe più logico convalidare l'input e su parametri imprevisti dare 400 (Richiesta non valida, molto generica), 422 ( Entità non processabile), che alcuni sostengono è migliore di 400 , vedi sotto. Meno applicabili sono 404 (Non trovato) - perché es6 è stato trovato, o forse in casi molto rari anche 501 (Non implementato).

L'utilizzo del codice HTTP 4xx farà risparmiare tempo agli utenti per la risoluzione dei problemi relativi all'accesso API.

Vedi anche qui ( 422 suggerito pure) o qui , che spiega perché 422 potrebbe essere più appropriato. Vedi anche questa domanda .

Personalmente, mi sono attenuto a 400 come codice HTTP ben noto e wide-spectrum.

A seconda del caso d'uso, alcuni parametri della stringa di query potrebbero essere ignorabili, ad esempio, quelli con prefisso di sottolineatura, per i casi in cui l'unico modo per impedire la memorizzazione nella cache sta cambiando l'URL per includere "impronte digitali".

    
risposta data 29.12.2017 - 17:34
fonte
1

level = ... sembra essere un problema di compatibilità con le versioni precedenti. Al fine di non frustrare gli utenti attuali, verificherei il livello come effettivamente ha fatto qualcosa nella versione precedente, ma non fa nulla nella versione corrente e fornisco un messaggio di avviso ("il livello è deprecato e attualmente non fa nulla") - ma non interrompere l'elaborazione. Darei l'errore come parte della risposta JSON rispetto all'errore http. Generalmente mi occupo di quelli relativi agli errori che impediscono l'elaborazione.

Se quello che stai sostenendo ha il potenziale per rilasciare una data personale (assistenza sanitaria o credito), allora nel caso di variabili extra o errate non vorrei restituire nulla. Se sono abbastanza persistenti, allora lo capiranno.

Se non vi è alcuna possibilità che le informazioni riservate si perdano, indicare come specifico l'errore / avviso che si desidera. In questo caso, inserirò i messaggi di avviso nella risposta JSON in quanto non influirebbe sul processo di elaborazione.

In entrambi i casi, dovresti controllare tutte le variabili e i valori passati per confermare che non ci siano script cross-site o iniezioni SQL o altri problemi di sicurezza.

    
risposta data 29.12.2017 - 17:57
fonte
1

Se sei disposto a dedicare tempo e sforzi per convalidare i parametri non utilizzati, ti suggerisco di rendere facoltativa tale convalida.

Ad esempio, è possibile accettare un flag strict=true (come intestazione di parametro o richiesta) che genera un errore se il client invia un parametro sconosciuto (o non utilizzato). Coloro che preferiscono reti di sicurezza basate su strumenti (ad esempio quelli che preferiscono un compilatore) probabilmente lo useranno sempre mentre quelli che hanno una preferenza diversa possono scegliere di limitarne l'utilizzo a fasi di sviluppo e / o di prova.

Alcuni framework web (ad es. Rails ) ignorano i parametri sconosciuti per impostazione predefinita. Questo può aiutare con la compatibilità diretta in quanto i tuoi clienti possono iniziare a chiedere una funzione anche prima che il tuo server la supporti. Ad esempio, puoi scegliere di abilitare il supporto per il parametro level in un secondo momento e i tuoi clienti non dovrebbero essere modificati.

    
risposta data 01.01.2018 - 19:52
fonte

Leggi altre domande sui tag