Come puoi far valere la conferma "vuoi davvero farlo" in un'API pubblicamente esposta?

5

C'è un motivo comunemente usato (o raramente) per un messaggio di "conferma di voler eseguire questo" quando si chiama una funzione da una libreria?

Ho un'API che espone alcune operazioni potenzialmente pericolose se utilizzate in modo improprio (causerebbero modifiche indesiderate al database). Vorrei passare un avvertimento al chiamante per ricontrollare che questo è apposta. Questo è sia per evitare che altri programmatori dell'organizzazione utilizzino erroneamente l'API e per impedire a un utente finale di eseguire accidentalmente questo comando da un modulo senza pensarci.

Ci sono davvero tre casi d'uso per questa funzione API:

  1. Eseguilo contro dati legit. Dovrebbe riuscire senza avvisi.
  2. Eseguilo contro i cattivi dati. Dovrebbe fallire con un'eccezione.
  3. Eseguilo contro dati discutibili. La logica di validazione vede che si tratta di un caso non standard, ma forse l'utente finale sa cosa sta facendo e lo fa apposta.

Ho cercato di pensare a un modo per inserire case 3 nella mia API.

In un modo in cui ho pensato di ruotare attorno a un "token di conferma"

Sub DoRiskyOperation(thisData As String, Optional confirmationToken As ConfirmationToken)

    If Not Validate(thisData) Then
        Throw New ArgumentOutOfRangeException("thisData", $"Cannot perform this operation on {thisData}.")
    End If

    If Not confirmationToken.ItsOK Then
        If Not TotallySafe(thisData) Then
           Throw New Warning("thisData", $"Are you sure you want to do this?", _
                             New ConfirmationToken(AreYouSure))
        End If
    End If

    'perform risky operation

End Sub

Un altro modo che stavo considerando è più un "chiedere prima" che a volte è disapprovato:

Enum PredictedSuccess
    WillSucceed
    WillFail
    WillSucceedButIsRisky
End Enum

Private LastDataAskedAbout As String

Function IsOperationRisky(thisData As String) As PredictedSuccess

    LastDataAskedAbout = thisData
    If Not Validate(thisData) Then Return PredictedSuccess.WillFail
    If TotallySafe(thisData) Then
        Return PredictedSuccess.WillSucceed
    Else
        Return PredictedSuccess.WillSucceedButIsRisky
    End If
End Function

Sub DoRiskyOperation(thisData As String)

    If Not Validate(thisData) Then Throw New ArgumentOutOfRangeException("thisData", $"Cannot perform this operation on {thisData}.")

    If Not TotallySafe(thisData) AndAlso LastDataAskedAbout <> thisData Then
        Throw New InvalidOperationException($"Hey, you were supposed to check before you try doing something this dangerous to {thisData}!")
    End If

    'perform risky operation

End Sub

Esiste un altro modo per codificare il concetto di questa "stretta di mano di conferma" in un'API a cui non sto pensando?

Nel caso in cui qualcuno fosse interessato, l'uso specifico - caso sta aggiornando il costo standard mentre c'è inventario a portata di mano. I ragionieri sono schizzinosi su questo genere di cose.

    
posta Mike 09.06.2016 - 18:35
fonte

5 risposte

15

Stai cercando di risolvere un problema di fattori umani con una soluzione a livello di API e credo che non funzionerà. È molto probabilmente il caso del problema XY .

Se il "rischio" sta perdendo i dati perché qualcuno ha fatto qualcosa di stupido (o dannoso), si dovrebbe eliminare del tutto questa possibilità (di perdita di dati). Non dovrebbero esserci metodi "rischiosi", perché gli errori umani non sono qualcosa che puoi eliminare.

I modi corretti per farlo potrebbero essere:

  1. Fool-proofing : esegui l'operazione in modo che venga creato il backup oppure i dati vengano contrassegnati come eliminati e non effettivamente eliminati, ecc.
  2. Funzione UI pericolosa (al contrario del cambiamento dell'API): aggiungi una finestra di dialogo di conferma all'interfaccia utente, con lettere maiuscole enormi e in grassetto che dicono "STAI PER CANCELLARE TUTTI I DATI". Inoltre, assicurati di registrare questa operazione in modo corretto, in modo da poter trovare sempre il dipendente arrabbiato che ha cancellato il tuo database e poi sono stati licenziati.
  3. Controllo degli accessi : attiva un'operazione rischiosa disponibile solo per le persone responsabili di possibili danni. Assicurati che capiscano il rischio. Non consentire l'accesso a nessun altro.
risposta data 09.06.2016 - 19:30
fonte
5

Uso il tuo primo approccio ma senza lanciare nulla. La subroutine prende un argomento in più, come il tuo - "So che questo è rischioso, ma fallo comunque", e restituisce tre possibili valori:

  • Successo
  • Guasto
  • Bloccato perché è rischioso e il chiamante non ha risposto "fallo comunque".

Oltre al tuo caso d'uso, questo è utile anche nel caso in cui l'operazione sia qualcosa che può richiedere o meno l'autorizzazione (come una password). In questo caso l'argomento extra è il token di autorizzazione e il terzo valore restituito è "Bloccato perché il token è mancante o non valido". Questo si adatta molto bene al caso in cui il programma chiamante a volte ricordi i token di autorizzazione per il riutilizzo.

    
risposta data 09.06.2016 - 19:04
fonte
5

La conferma non è propriamente appropriata per un'API. Il punto di "sei sicuro?" la conferma è di consentire a un utente umano di pensarci due volte prima di eseguire un'operazione potenzialmente distruttiva. Un'API viene chiamata per codice, quindi qualsiasi forma di conferma dovrà essere programmata nel client dall'inizio, rendendo così l'ammonimento dell'avviso.

Suggerisci che la conferma possa essere trasmessa a un utente che interagisce con il cliente. Ma questo rompe la separazione delle preoccupazioni. L'intero punto di un'API è che non gli interessa se viene chiamato come parte di un'operazione manuale o se viene chiamato tramite uno script o altro.

Quindi dimenticate il "token di conferma" e progettate l'API in modo tale che comunichi chiaramente agli sviluppatori client che una determinata operazione è potenzialmente pericolosa. Ad esempio, potresti avere due versioni di una chiamata:

DriveForwardIfSafe()
DriveForwardIgnoreAllWarnings()

Questo comunica molto chiaramente allo sviluppatore del client che una versione è potenzialmente pericolosa e gli sviluppatori che decidono di chiamare la versione "non sicura" lo faranno sapere.

    
risposta data 01.01.2017 - 17:46
fonte
0

Le finestre di dialogo di conferma non sono normalmente una preoccupazione dell'API, sono una preoccupazione per l'interfaccia utente, perché riguardano la possibilità che un umano fallibile e incoerente cambi idea o corregga i codici errati e i clic sbagliati prima che hanno commesso le loro azioni.

Detto questo, ci sono delle eccezioni alla norma.

Molti servizi forniscono la funzionalità cronologia e / o annulla , ad esempio. Nel caso in cui l'API sia lontana dall'effettivo utente finale, o quando le interazioni stesse debbano essere fluide ed efficienti, memorizzare un certo livello di cronologia e consentire operazioni di annullamento.

E se, per qualsiasi ragione, l'operazione fosse totalmente irreversibile, come lanciare un missile, la tua API dovrebbe richiedere un codice di autorizzazione, possibilmente un codice monouso, e possibilmente da più utenti. Ma questo probabilmente verrebbe raccolto durante la chiamata iniziale pericolosa - non avresti lanciato un'eccezione per avvertire l'utente del pericolo. La presenza del token di autenticazione lo indica.

    
risposta data 02.01.2017 - 01:44
fonte
-1

Avrei bisogno di una sovvenzione aggiuntiva per l'operazione. Per esempio. l'operazione può essere eseguita solo se si ha su. E su può essere concesso solo temporaneamente. Pertanto, per richiamare questa operazione, è necessario prima richiedere un'autorizzazione temporanea, quindi richiamare l'operazione prima che su scada.

    
risposta data 02.01.2017 - 00:37
fonte

Leggi altre domande sui tag