2015-10-29 12 views
16

In riferimento a this link, ho visto molti esempi di utilizzo di HyperlinkedModelSerializer in Django Rest Framework. Dice:Qual è il vantaggio dell'utilizzo di un HyperlinkedModelSerializer in DRF?

classe L'HyperlinkedModelSerializer è simile alla classe ModelSerializer eccezione che utilizza i collegamenti ipertestuali per rappresentare le relazioni, piuttosto che le chiavi primarie.

La mia domanda è, qual è il caso d'uso/vantaggio di usarli rispetto a un normale serializzatore di modello?

risposta

16

L'unica differenza è che, come nella citazione che hai incluso, le chiavi primarie e quelle estranee sono rappresentate da URL che puntano a quelle risorse, anziché solo valori chiave effettivi.

Il vantaggio è che non sarà necessario costruire gli URL delle risorse nel frontend quando si desidera recuperare gli oggetti correlati.

Un'altra cosa è rappresentazioni nidificate che consente di allineare oggetti correlati nell'output del serializzatore. Questo può essere combinato con ModelSerializer e HyperlinkedModelSerializer quando ritieni che sia più conveniente per il consumatore dell'API avere subito gli elementi correlati invece di fare richieste aggiuntive per recuperarli.

Le rappresentazioni nidificate possono essere implementate tramite l'opzione Meta.depth o utilizzando il serializzatore del modello correlato anziché RelatedField.

Come ha detto @xleon nel suo commento utilizzando gli URL come chiave, è più semplice per gli sviluppatori capire la propria API.

+6

Risposta piacevole, vorrei aggiungere solo una cosa: l'utilizzo di collegamenti ipertestuali nelle risorse renderà più semplice per qualsiasi sviluppatore che utilizza l'API Web. Se possono vedere l'intero URI delle risorse, non avranno bisogno di documentazione o altri modi per scoprirlo. – xleon

4

Abbiamo bisogno di implementare relazioni tra entità nella progettazione di API Web. Ci sono diversi modi per farlo (come menzioni sulla documentazione DRF):

  • Utilizzo di chiavi primarie.
  • Utilizzo del collegamento ipertestuale tra entità.
  • Utilizzo di un campo di identificazione univoco identificativo sull'entità correlata.
  • Utilizzo della rappresentazione di stringa predefinita dell'entità correlata.
  • Annidamento dell'entità correlata all'interno della rappresentazione padre.
  • Qualche altra rappresentazione personalizzato

Il HyperlinkedModelSerializer presenta le seguenti differenze da ModelSerializer:

  • non include il campo ID per impostazione predefinita.
  • Include un campo url, che utilizza HyperlinkedIdentityField.
  • Le relazioni utilizzano HyperlinkedRelatedField, anziché PrimaryKeyRelatedField.

Un semplice esempio:

class UserSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = User 
     fields = ('url', 'username', 'email', 'groups') 


class GroupSerializer(serializers.HyperlinkedModelSerializer): 
    class Meta: 
     model = Group 
     fields = ('url', 'name') 

bash> http -a admin: VOSTRAPASSWORD http://127.0.0.1:8000/users/

"results": [ 
     { 
      "email": "[email protected]", 
      "groups": [ 
       "http://127.0.0.1:8000/groups/1/", 
       "http://127.0.0.1:8000/groups/2/" 
      ], 
      "url": "http://127.0.0.1:8000/users/1/", 
      "username": "admin" 
     } 
    ] 

Ma se si cambia

class UserSerializer(serializers.ModelSerializer): 
     class Meta: 
      model = User 
      fields = ('url', 'username', 'email', 'groups') 

Il risultato sarà:

"results": [ 
     { 
      "email": "[email protected]", 
      "groups": [ 
       1, 
       2 
      ], 
      "url": "http://127.0.0.1:8000/users/1/", 
      "username": "admin" 
     } 
    ] 
+0

Esempio chiaro, grazie! –

0

Uno costo di HyperlinkedModelSerializers che va notato è che se l'API supporta il filtraggio o ordinare tramite parametri di query nell'URL è un po 'più difficile per il vostro consumatore frontend per utilizzare i campi URL collegamento ipertestuale per la costruzione di params query perché devono analizzare il pk dall'URL piuttosto che avere il pk direttamente disponibile.

Ad esempio, ipotizzando un oggetto su un percorso a /api/objects/12/ consumatore dovrebbe analizzare il campo url per estrarre il 12 per costruire un filtro query questo oggetto su un altro nodo finale: /api/otherobjects/?object=12. Non è un problema enorme, ma un problema se si prevede di fare un sacco di filtraggio.