Logica delle applicazioni RESTful e operazioni cross cross

4

Dispongo di un'API RESTful che consente ai miei utenti di ricevere richieste di informazioni sulla propria attività, ad es. 'Vorrei prenotare il servizio x alla data y. È disponibile? '. L'API salva queste informazioni come una risorsa per il seguente URI

users/{userId}/enquiries/{enquiryId}

Le informazioni mostrate quando questa risorsa viene recuperata sono le cose standard che ci si aspetterebbe da una richiesta - email, first_name, last_name, indirizzo, messaggio

L'API consente anche ai clienti di essere creati per un utente. Il cliente ha un login e una password e anche un profilo. I seguenti URI espongono queste due risorse

PUT users/{userId}/customers/{customerId}
PUT users/{userId}/customers/{customerId}/profile

Il problema che sto avendo è che mi piacerebbe avere la possibilità di consentire agli utenti di creare un cliente da una richiesta. Ad esempio, l'utente è in grado di offrire il proprio servizio alla data richiesta e quindi desidera configurare un cliente con i dettagli di accesso, ecc. Per consentire loro di gestire il resto del processo.

La risposta ovvia sarebbe utilizzare un URI come

 users/{userId}/enquiries/{enquiryId}/convert-to-client

Il problema con questo è che in qualche modo va contro molto di quello che ho letto su come implementare REST (in particolare dal libro Restful Web Services che suggerisce che gli URI dovrebbero puntare a risorse e non operazioni su risorse).

L'altra opzione sarebbe quella di ottenere l'applicazione client (cioè il codice che chiama l'API) per gestire parte di questa logica dell'applicazione. Questo non mi sembra giusto. Ho implementato nel mio progetto che l'app client è abbastanza stupida. Sa solo quanto basta per visualizzare i risultati dall'API e non contiene alcuna logica applicativa.

Sarebbe bello sapere quali sono le visualizzazioni degli altri sul modo migliore di configurarle

Ho sbagliato a non avere alcuna logica di applicazione nell'app client? Come eseguirò questa operazione esclusivamente nell'API REST?

    
posta Gaz_Edge 02.07.2013 - 00:11
fonte

3 risposte

4

I altamente consiglia di leggere RESTful Webservices , in particolare i capitoli sulla differenza tra Programmazione web in stile RESTful e RPC; e i capitoli sulla scoperta delle risorse e su come affrontare l'apparente necessità di "verbi" (di solito sono una risorsa diversa sotto mentite spoglie).

La conversione di una richiesta in un cliente non richiede un verbo "converti". Non elimineresti la richiesta solo perché crei un cliente e quindi stai semplicemente creando un cliente con le informazioni della richiesta come input.

POST /users/{userId}/customers?enquiry={EnguiryId}

o semplicemente

POST /users/{userId}/customers

con le informazioni di richiesta nel corpo della richiesta.

A proposito, uso il POST sui clienti perché questo è il modo di farlo se l'applicazione server ha il controllo della generazione dell'identificatore. Usa PUT solo per creare risorse se il chiamante è quello che determina gli identificatori.

Nota a margine: hai preso in considerazione i problemi di sicurezza e privacy relativi all'inclusione / utenti / {UserId} nell'URI? Ora chiunque può iniziare a provare diversi ID utente per ottenere informazioni sui diversi utenti dell'applicazione. Dovresti davvero considerare di lasciarli fuori dall'URI e di averli determinati dalle informazioni di autenticazione che dovrebbero essere inviate con ogni richiesta (e eventualmente aggiornate con ogni risposta).

    
risposta data 02.07.2013 - 09:02
fonte
2

Prendendo in considerazione l'esempio che offri, ho un aspetto completamente diverso. Le altre risposte sono corrette, ma penso che ciò derivi da un punto di partenza sbagliato.

In effetti un'inchiesta è una richiesta proveniente da un cliente. Un cliente può forse avere più richieste?

Quando inizi a ottenere la necessità di avere un passaggio di conversione, significa che molte volte hai 2 risorse che sono circa uguali.

Perché non avere solo la risorsa Cliente all'inizio. Quella risorsa contiene tutte le informazioni sul client: email, first_name, last_name, indirizzo.

Stato ora: un cliente senza richieste. Quindi questo è un vantaggio (potresti aggiungere un campo booleano per quello stato).

Quindi potresti definire 2 cose: potresti dare al Cliente un campo con il messaggio (primo contatto o qualcosa che potrebbe essere chiamato in quel campo).

Stato ora: hai un cliente con un messaggio in modo da poterlo filtrare e iniziare a rispondergli

In alternativa, puoi creare e richiedere il cliente. Quindi, prima creare un cliente, quindi una richiesta. Questo potrebbe essere fatto dal cliente, tu devi rendere ClientId necessario per creare una richiesta.

Potresti anche fare questi 2 passaggi in uno consentendo di creare una nuova richiesta con campi opzionali (i campi degli indirizzi dei clienti). Questo può prendere entrambi i passaggi contemporaneamente. Non mi piace particolarmente perché è meno semplice e alla fine si ottiene una maggiore complessità senza quasi nessun vantaggio.

Stato ora: hai un cliente con una richiesta correlata.

Ora hai più clienti nel tuo database che potrebbero piacerti. Li puoi filtrare in modo da ottenere l'elenco corretto dei clienti. Sono gli stessi dati quindi credo che appartengano alla stessa risorsa.

    
risposta data 02.07.2013 - 09:37
fonte
0

The problem with this is is that it somewhat goes against a lot of what I've been reading about how to implement REST (specifically from the book Restful Web Services which suggests that URIs should point to resources not operations on resources).

Questo è corretto perché la seguente operazione che hai suggerito nella tua domanda sarebbe appropriata solo per un servizio SOAP. REST incoraggia a non dichiarare il servizio come un'azione di una risorsa in alcun modo. Il protocollo HTTP definisce l'operazione sulla risorsa con GET, POST, PUT, DELETE, ecc ...

Per essere REST si esegue un'operazione HTTP su una risorsa, e il risultato di ciò restituisce una Rappresentazione di detta Risorsa (Get it? Representational State Transfer). Se il cliente desidera ottenere una richiesta, deve modificare la rappresentazione di tale risorsa e inviare tali dati al server. Anche se potresti preoccuparti di implementare questa modifica dei dati sul client, questo non è intrinsecamente contrario ai vincoli definiti da REST.

Fonte: Wikipedia: Representational State Transfer - Constraints

Code on demand (optional) Servers can temporarily extend or customize the functionality of a client by the transfer of executable code. Examples of this may include compiled components such as Java applets and client-side scripts such as JavaScript.

È perfettamente accettabile quindi supporre che un oggetto JSON implementato in modo corretto orientato agli oggetti abbia un comportamento definito dello script su come trasformare i suoi dati in uno stato che può essere postposto sul server per convertirlo in un cliente. Questa funzionalità potrebbe non essere necessariamente complessa, forse è anche solo una proprietà dell'oggetto JSON stesso che quando POST restituisce che il server capisce che deve essere convertita.

Il problema è che la rappresentazione di questa risorsa cambierà e questo deve essere comunicato o documentato chiaramente ai clienti del servizio.

    
risposta data 02.07.2013 - 03:11
fonte

Leggi altre domande sui tag