Progettazione REST per azioni "complicate" che riguardano più di una risorsa

3

Sto provando a progettare un RESTful (o forse dovrei dire RESTlike, dal momento che non sto progettando un'API pienamente RESTful, ad esempio non guidata dall'ipertesto) come parte di un refactoring di un esistente "take-a- numero "sistema di gestione di accodamento .

I concetti di base e il flusso di lavoro sono:

  • Un determinato sito (posizione) può proporre diversi servizi e avere più desk. Ogni desk può fornire uno o più servizi sul sito. (ad esempio in una banca, puoi avere un ufficio informazioni, scrivanie per operazioni comuni come un deposito e scrivanie dove puoi sederti per parlare con un consulente per cose più complesse, ad esempio aprire un nuovo account o richiedere un mutuo)

  • Quando entra nell'edificio, un cliente stampa un biglietto selezionando un servizio su uno schermo tattile . (ad esempio "Apri un nuovo account"). D'ora in poi il ticket verrà tracciato nello stato interno del server.

  • Il ticket rimane in coda per un po '

  • L'operatore della scrivania chiama il prossimo cliente facendo clic su un pulsante. Il sistema determina quale è il prossimo biglietto adatto per la scrivania (dato che non tutti gli sportelli forniscono gli stessi servizi)

  • Una volta che il ticket è stato chiamato su una scrivania, viene visualizzato un evento e un sistema di visualizzazione mostra il numero del ticket insieme al desk dove il cliente dovrebbe andare

  • Quando il cliente arriva alla scrivania , l'operatore fa clic su un altro pulsante, quindi segnala l'inizio della fornitura effettiva del servizio

  • Una volta che il servizio è stato fornito e il cliente lascia , l'operatore della scrivania fa clic su un altro pulsante, il ticket viene archiviato e il banco torna libero. Fino a quando l'operatore non chiama il prossimo ticket.

Esiste un server centrale e 2 tipi di app client: il terminale di distribuzione dei biglietti e il client della GUI della scrivania.

Quindi, in termini di risorse REST, una delle risorse principali è il ticket. Innanzitutto, viene creato un nuovo ticket (POST) e viene attribuito un numero. È facile.

Ma allora non so come modellare le transizioni allo stato del ticket che sono avviate dal client desk, dal momento che non sono solo aggiornamenti del ticket ma attivano la logica di business che viene eseguita sul server e ha side- effetti non solo sul biglietto:

  • Chiama il prossimo ticket (provoca una modifica dello stato sul server, il ticket viene prelevato dalla coda, associato al desk che lo ha chiamato e contrassegnato come "chiamato")
  • Segnala al server che il cliente è arrivato alla scrivania (provoca una modifica dello stato sul server, il ticket è contrassegnato come "in fase di pubblicazione", ancora associato alla scrivania)
  • Segnala il server che il cliente ha lasciato (causa una modifica sul server, il ticket è separato dalla scrivania, contrassegnato come "servito", inserito in una raccolta di tutti i ticket serviti, e una voce di registro è scritta nel DB)
  • Segnala al server che il cliente non è arrivato ( no show ) e il ticket viene annullato (provoca una modifica sul server, il ticket viene separato dalla scrivania, inserito in una raccolta di tutti i biglietti annullati, contrassegnati come "non serviti" e una voce di registro viene scritta nel DB)

Etc.

Tutte queste operazioni dovrebbero essere eseguite anche in modo atomico e in modo sincrono.

Si adattano bene alle "azioni", ad esempio RPC, e questo è il modo in cui è stato implementato nelle versioni precedenti del sistema (ovvero le chiamate RMI). Ad esempio, il desk può "chiamare il prossimo ticket" (un'azione) e recupera il prossimo ticket corrispondente.

Come modellarli in modo RESTful?

Inoltre, ne vale la pena, o dovrei semplicemente essere un po 'flessibile su RESTfulness e modellarlo come "azioni" o qualcosa di simile (quindi in pratica RPC su HTTP)?

Grazie per i tuoi pensieri!

    
posta Pierre Henry 27.01.2017 - 10:56
fonte

2 risposte

3

Tutte le operazioni menzionate sono modifiche allo stato del ticket, quindi perché non modellarle come operazioni sulla risorsa Ticket?

  1. Il client di registrazione cliente crea un nuovo ticket: POST /tickets
  2. Il client Desk aggiorna l'elenco di ticket, assegnando il dipendente al ticket con PATCH request a /tickets/next e JSON body { "employee_id" : "5" } . La risposta sarà HTTP 301 con Location intestazione che punta a ticket specifico: /tickets/172 Questa richiesta invierà anche un messaggio asincrono ai seguenti utenti:
    • display service, che mostra lo stato della coda sui monitor nella stanza, per avvisare che la coda è stata aggiornata e i client devono recuperare nuovi contenuti.
    • call expiration job, che aggiornerà il ticket se il cliente non arriverà in un dato momento.
  3. Se il cliente arriva alla scrivania, il client desk invia la richiesta PATCH al ticket specifico /tickets/172 , che aggiorna lo stato del ticket e invia un messaggio asincrono agli abbonati citati. In questo caso, il lavoro di scadenza della chiamata verrà respinto per questo ticket dopo aver ricevuto il messaggio.
  4. Al momento della pubblicazione del ticket, il client desk eseguirà la richiesta PATCH per aggiornare lo stato del ticket.
  5. Se il cliente non arriva entro un determinato periodo di tempo, il processo di scadenza della chiamata eseguirà la richiesta PATCH sull'URI fornito in messaggio asincrono prima di aggiornare lo stato del ticket. Durante l'elaborazione di questa richiesta, il messaggio async per visualizzare il servizio rimuoverà il ticket dalla visualizzazione della coda.

Tutte queste operazioni sono atomiche dal punto di vista del cliente e i dettagli di implementazione delle operazioni atomiche non devono essere esposti. Per quanto riguarda i log, sono necessari per mantenere gli SLA API e non come una funzione aziendale, quindi sono in effetti dettagli di implementazione che non sono noti ai client ed è sicuro non considerare i registri come effetti collaterali.

    
risposta data 27.01.2017 - 12:56
fonte
1

Solo RPC: -)

Non provare a scrivere tutto su un modello di "risorse". I parametri di un'azione possono essere considerati come "risorse". Anche se tu potessi, non significa che dovresti.

Quando usi RPC cerca di evitare di diventare troppo loquace e rendere le tue azioni completamente contenute, atomiche, con una sola operazione di chiamata che non richiede un follow-up immediato.

Quindi non deselezionare un biglietto in una sola chiamata e quindi assegnarlo a una scrivania in un'altra. Richiama un'azione che farà entrambe le cose, ad es. 'Assegnare-new-ticket-to-desk'. Lasciando il sistema in uno stato coerente dopo.

    
risposta data 27.01.2017 - 11:29
fonte

Leggi altre domande sui tag