2014-07-10 17 views
5

Ho un'API RESTful che sto progettando che utilizza chiavi primarie numeriche per tutte le sue risorse. Tuttavia un tipo di risorsa ha una comoda chiave naturale, che mi piacerebbe poter usare come un modo opzionale per specificare la singola risorsa. Per coerenza, tutte le risorse saranno accessibili tramite la loro chiave primaria.Natural keys e RESTful URL

Così com'è, posso fare questo (supponendo 23 è la chiave primaria):

mysite.com/api/v0/sites/23/ 

Tuttavia, mi chiedo se c'è un idiomatica modo per specificare una chiave naturale alternativa per una risorsa .

Finora Stavo pensando di fare qualcosa di simile:

mysite.com/api/v0/sites/?domain-name=someothersite.com/ 

Così una singola risorsa sito sarebbe accessibile sia la sua chiave primaria e una chiave naturale (il suo nome di dominio). La mia preoccupazione principale è fare questo in modo idiomatico, visto che mi piacerebbe rendere l'API più semplice da usare possibile.

+0

Bello, voglio dire che non ho mai pensato a 'v0' negli esempi ma ha senso. :-) – inf3rno

risposta

2

Nella tua situazione particolare, la chiave primaria (numero intero) può sempre essere facilmente differenziata dal nome del dominio (stringa che include un punto). Sembra perfettamente valido (e intuitivo) per consentire sia nella stessa posizione del URL:

mysite.com/api/v0/sites/23 
mysite.com/api/v0/sites/someothersite.com 

documentare che è semplice anche, come ciascuno è un identificatore univoco per un sito:

mysite.com/api/v0/sites/{id} 
    id: primary key or fully-qualified domain name 
1

I Ho anche faticato a trovare una risposta soddisfacente a questa domanda. Avevo già iniziato a implementare lo stesso suggerimento di Mike Dunker, ma alla fine ho incontrato alcune risorse per le quali non è possibile distinguere tra la chiave surrogata e la chiave naturale. Fu allora che mi resi conto che avrei preferito un approccio uniforme a questo invece di mescolare modi diversi - come dici tu, qualcosa di idiomatico.

Un altro approccio che ho trovato è descritto in http://soabits.blogspot.de/2013/10/url-structures-and-hyper-media-for-web.html (sotto "Chiavi naturali, chiavi surrogate, alias URL e duplicazione delle risorse").

L'idea è definire uno dei due possibili schemi chiave come quello canonico e realizzare l'altro aggiungendo un segmento all'URI e utilizzando un HTTP 303 (Vedi Altro) per reindirizzare all'URI canonico.

Quindi nel tuo esempio, si potrebbe avere mysite.com/api/v0/sites/23/ come ID canonica e mysite.com/api/v0/sites/domain-name/someothersite.com/ rispondeva con HTTP 303 e un colpo di testa posizione contenente mysite.com/api/v0/sites/23/ (o viceversa). L'utilizzo di reindirizzamenti per gli alias URI invece di "duplicare" la stessa risorsa è utile per i motivi indicati allo http://www.w3.org/TR/webarch/#uri-aliases.

Il motivo per cui non sono andato con questa soluzione è il giro di andata HTTP aggiuntivo, che potrebbe essere troppo costoso nella configurazione del nostro progetto.

0

Ecco un'idea un po 'più robusto di Mike's utilizzando un param key per indicare la chiave naturale l'ID di risorsa si riferisce a:

mysite.com/api/v0/sites/23 

e

mysite.com/api/v0/sites/someothersite.com?key=domain-name 

nel controller è possibile convalidare il parametro chiave è solo la tua chiave naturale, piuttosto che dire di interrogare le meta informazioni della tabella per gli indici univoci. Se non ti piace inquinare la stringa della query potresti anche usare un'intestazione HTTP.

0

Tenere presente che le entità ORM o le entità di dominio non sono risorse. Può esserci una mappatura tra queste entità e le risorse. La risorsa è un concetto di interfaccia di applicazione, è possibile descrivere l'interfaccia del servizio con risorse e operazioni su queste risorse.

Quindi la chiave primaria non identifica una risorsa, identifica un'entità. Le risorse sono identificate dagli URI. Gli URI non sono identificatori univoci, quindi è possibile utilizzare più URI per identificare una singola risorsa.

Mark è giusto, è possibile utilizzare un simile modello di URI

mysite.com/api/v0/sites/{id} 
mysite.com/api/v0/sites/{hostname} 

se il quadro di routing supporta differenziazione tra percorsi per tipo. Quindi se il tipo è numerico, verrà eseguita la route ID e se il tipo corrisponde a un modello di espressione regolare dell'host, verrà eseguita la route del nome host. Altrimenti puoi unire i 2 percorsi e gestire la differenziazione tra loro manualmente con il tuo codice.