I risultati non riusciti dovrebbero essere errori o dati in RESTFul?

3

Supponendo di avere un servizio RESTful e risponde sempre in questo formato:

{
    "error": { 
        "code": ...,
        "message": ...
    }
}

or

{
    "data": ...
}

e c'è un metodo come POST /users/me/change-password .
Quale sarebbe il comportamento corretto e RESTful:

  1. Gli errori di logica / convalida aziendale sono dati

    • La password è stata modificata (200, errore e dati vuoti)
    • L'utente non è autenticato (401, error = 1, empty data}
    • Criterio password: la password è già stata utilizzata (200, errore vuoto, dati = 1)
    • Criterio password: la password non corrisponde ai requisiti (200, errore vuoto, dati = 2)
    • Richiesta conferma SMS-OTP (200, errore vuoto, dati = 3)
    • SMS-OTP errato (200, errore vuoto, dati = 4)
    • L'utente ha disabilitato la modifica della password (200, errore vuoto, dati = 5)

    Sembra corretto poiché errori come "Conferma SMS-OTP richiesta" non sono nemmeno errori del client. Un client non ha fatto nulla di male e si aspetta una risposta "OK".

  2. I risultati della logica aziendale / di convalida sono errori

    • La password è stata modificata (200, errore e dati vuoti)
    • L'utente non è autenticato (401, error = 1, empty data}
    • Criterio password: la password è già stata utilizzata (400, errore = 2, dati vuoti)
    • Criterio password: la password non corrisponde ai requisiti (400, errore = 3, dati vuoti)
    • Richiesta conferma SMS-OTP (400, errore = 4, dati vuoti)
    • SMS-OTP errato (400, errore = 5, dati vuoti)
    • L'utente ha disabilitato la modifica della password (400, errore = 6, dati vuoti)

    Sembra corretto dal momento che lo stato 200 OK suggerisce che la password è stata cambiata correttamente, qualunque sia stata scritta in risposta. Tuttavia, alcuni client come C # WebClient non restituiscono nemmeno risposte non OK, ma generano eccezioni.

Le stesse domande sorgono in termini di tutte le richieste di autenticazione. Ad esempio, "username è già occupato" per "accedere" a un errore o dati.

    
posta Yeldar Kurmangaliyev 15.12.2016 - 06:31
fonte

2 risposte

1

I guru di REST ti diranno che ogni possibile errore ha un codice di errore HTTP che si associa ad esso.

Tuttavia, prima di essere coinvolti in questa follia, dovremmo ricordare che il lancio di eccezioni non dovrebbe essere la tua prima scelta per la restituzione dei dati all'utente.

In questo caso mi sembra che se si rifatta il metodo 'cambia password' per restituire un oggetto, o anche solo una metà bool di quelle eccezioni scompare.

Penso che questa sia la scelta giusta per le situazioni in cui si verificano più errori, ad esempio la password non soddisfa i criteri per le password forti x, yez.

mantieni le eccezioni per cose eccezionali, ad es. utente non trovato o accesso negato.

Questo richiama le possibili risposte che il consumatore deve gestire in modo specifico e consente loro di lasciare (90%) le eccezioni al gestore predefinito "mostra errore all'utente".

Nota: questo è diverso dal restituire l'eccezione come oggetto json con un codice di risposta di 200. Che dovrebbe essere evitato.

ad es.

public class PasswordChangeResult
{
    public bool PasswordChanged;
    public List<string> ValidationErrors;
}

OPPURE un errore HTTP

è sempre restituito.

    
risposta data 15.12.2016 - 10:16
fonte
-1

Business logic / validation results are errors

Questa è la risposta corretta per REST.

REST è il trasferimento di stato. Il client fa qualcosa su una risorsa e trasferisce il nuovo stato sul server.

Dovresti cambiare la risorsa da /users/me/change-password a /users/me/password e il verbo HTTP da POST a PUT.

Il client sta dicendo "Ecco il nuovo stato della password degli utenti, ora è questo " e invia quel messaggio al server. Il server può accettare l'aggiornamento di stato o rifiutarlo.

Se il server rifiuta l'aggiornamento, dovrebbe restituire un errore. Il cliente deve sapere che il trasferimento di stato non ha avuto luogo. Ma cerca di non pensare ai codici di risposta HTTP 4xx come aventi significati diversi a seconda del tuo dominio specifico. Si riferiscono alla parte di trasferimento dello stato della comunicazione, non al dominio. La maggior parte si occupa dei meccanismi del trasferimento di stato (il tuo messaggio è sintatticamente corretto, c'è stato un errore di rete, sei autenticato, ecc.)

Ad esempio 400 significa cattiva richiesta dal punto di vista della formattazione della richiesta HTTP. Se la richiesta al server è stata una richiesta HTTP perfettamente valida ma il server la sta respingendo per qualche motivo aziendale, non dovrebbe rispondere 400

Spesso la risposta corretta è 403 Proibita quando una regola aziendale non riesce e il server rifiuta la richiesta di aggiornamento dello stato. Se ci pensi in questo modo, il server sta dicendo al client "Tutto è sintatticamente soddisfacente con questa richiesta, ma ora consentirò questo aggiornamento a causa di questo motivo" , in pratica vietando l'aggiornamento.

Potresti avere

403 Forbidden Password has already been used

e

403 Forbidden Password doesn't match requirements

Entrambi sono validi. I 4xx non sono progettati per dire al cliente la ragione specifica del dominio che il server non ha fatto qualcosa. Questo è il corpo della risposta e un client deve comprendere sia i codici di risposta HTTP generali che i messaggi specifici dei corpi di risposta

    
risposta data 15.12.2016 - 18:34
fonte

Leggi altre domande sui tag