2014-09-08 4 views
5

Desidero scrivere un'app Django con un REST-ful api. framework Django REST offre tre serializzatori modello built-in: ModelSerializer che serializza a qualcosa di simileQual è la procedura migliore per serializzare i campi di chiave esterna in una API REST-ful

{ 
    'normal_field': 'value', 
    'foreign_key_field': 42 
} 

e HyperlinkedModelSerializer che serializza a qualcosa di simile

{ 
    'normal_field': 'value', 
    'foreign_key_field': 'http://domain/api/myothermodel/11' 
} 

La mia domanda è se c'è un altro buon modo per serializzare i dati in modo che il client sappia direttamente quali campi devono essere risolti e quali campi no.

Esempio: Un client che riceve questo

{ 
    'foo': 'http://domain/api/myothermodel/11', 
    'bar': 'http://otherdomain/api/myothermodel/12' 
} 

non sa se foo o bar dovrebbe essere un campo chiave esterna risolvibile e non un URL semplice. Qualcosa di simile:

{ 
    'foo': 'http://domain/api/myothermodel/11', # Here the client might know that this is only a plain url. 
    'bar': { 
      '_foreignkey': true, # Tells the client that this field should behave as a foreign key which has to be resolved first 
      'url': 'http://otherdomain/api/myothermodel/12' 
     } 
} 

Esiste uno standard o una procedura ottimale? O è meglio che il client non lo sappia dal JSON ma da un altro codice che ha o ottiene dal server?

Aggiornamento: Facoltativo: è possibile aggiungere quale via è consigliata per alcune librerie client note come AngularJS.

+0

Questa è in realtà una domanda interessante che non ho pensato. Per noi i frontend sanno in anticipo cosa deve essere risolvibile – timop

+0

Potresti chiarire cosa intendi per ** una chiave straniera che deve essere risolta prima **? Per soluzione, intendi che l'istanza correlata ha un punto finale di ubicazione della risorsa nell'API REST? E risolto prima, prima di quale operazione specifica? – Fiver

+0

Sì: "Risolvi" indica che i dati rappresentano informazioni per ottenere l'istanza correlata. "Primo" significa che voglio finalmente mostrare l'istanza e tutte le istanze correlate sul mio sito. Quindi il client deve seguire tutte le relazioni e recuperare le istanze prima che la pagina possa essere resa. MA: Nel mio primo esempio non è ovvio che i dati siano informazioni "risolvibili" ma non solo dati semplici. Questo rende più chiaro? – Norman8054

risposta

4

Sembra che tu stia cercando un servizio API web descrivente ed esplorabile, che è in realtà una caratteristica fondamentale del concetto REST originale indicato come Hypermedia as the Engine of Application State (HATEOAS). In sostanza, un servizio Web conforme a HATEOAS non si basa su alcuna conoscenza preliminare delle risorse del sistema oltre al punto di ingresso dell'URL iniziale.

Ciò è in contrasto con un Service Oriented Architecture (SOA) in cui i singoli servizi sono sostanzialmente non associati e richiedono una conoscenza preliminare della loro esistenza per raggruppare più chiamate di servizio per eseguire alcune attività con più risorse, eventualmente correlate.

La maggior parte dei riferimenti a un'API REST in realtà non sono completamente RESTful e dovrebbero essere descritti in modo più accurato come API Web, in quanto sono più in linea con la progettazione SOA: un insieme di URL per istanze specifiche e raccolte di istanze di un tipo particolare. Ciò includerebbe anche l'uso di diversi verbi HTTP (GET, PATCH, POST, PUT) per varie azioni da eseguire su quelle risorse. Il Django REST quadro (DRF) in realtà ha una pagina su questo argomento con i collegamenti alle grandi risorse sul vero progetto RESTful, compresa la tesi di Roy Fielding:

http://www.django-rest-framework.org/topics/rest-hypermedia-hateoas

vorrei ipotizzare che l'uso corrente di il termine "API REST" si riferisce alla rivelazione di molti sviluppatori che implementare un servizio veramente RESTful è tutt'altro che banale e in molti casi sarebbe eccessivamente ingegnerizzato per il particolare caso d'uso. Forse questo è un buon esempio di "perfezione come nemico del bene". Per il caso di usare AngularJS come framework lato client per interagire con un backend Django tramite DRF, questo è particolarmente vero. Non c'è nulla nel framework AngularJS che analizzi un progetto veramente RESTful per fornire automaticamente i vari stati dell'applicazione possibili per una determinata risorsa. Inoltre, gli stessi sviluppatori di solito sono responsabili sia del codice JavaScript che di Python, quindi la mancanza di un'API auto-descrittiva non rappresenta un ostacolo importante allo sviluppo.

Per quanto riguarda l'implementazione di una vera API RESTful in JSON, ci sono un paio di progetti che tentano di facilitare questo, vale a dire lo Hypertext Application Language (HAL) e JSON Linked Data (JSON-LD). Tuttavia, non sono a conoscenza del fatto che DRF supporti in modo nativo uno di questi due, quindi è probabile che tu debba architettare i tuoi serializzatori per conformarli ad uno di essi, o eseguire il rollover della tua implementazione di Django REST.

Infine, qualunque sia il disegno scelto, la documentazione completa dell'API è solitamente una buona idea. Questo è vero indipendentemente dal fatto che l'API sia basata sul web o in qualche linguaggio di programmazione nativo. Parte del fascino per la separazione delle preoccupazioni che fornisce un'API Web è che terze parti possono consumare risorse per creare applicazioni o pipeline che non sono state considerate, per non parlare dei vantaggi in termini di manutenibilità per le future modifiche al codice di base per il progetto . Ci sono un paio di interessanti progetti mentioned on the DRF site per aiutare a documentare un'API. Swagger è particolarmente bello, sviluppato dallo stesso sviluppatore che ha fornito il vecchio pacchetto di documenti Django REST Framework.

+0

Grande. Discuterò di questo con i miei colleghi e vedremo cosa usare. Grazie mille. – Norman8054