What is the benefit of using a HyperlinkedModelSerializer in DRF?
Asked Answered
M

4

95

In reference to this link, I've seen plenty of examples of using a HyperlinkedModelSerializer in Django Rest Framework. It says:

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys.

My question is, what is the use case/benefit of using them vs a regular Model Serializer?

Minier answered 29/10, 2015 at 17:42 Comment(0)
P
72

The only difference is, as in citation you included, that primary and foreign keys are represented by URLs that point to those resources, instead of just actual key values.

The benefit is that you will not have to construct resource URLs in your frontend when you want to retrieve related objects.

Another thing entirely is nested representations which allows you to inline related objects in your serializer output. This can be combined with both ModelSerializer and HyperlinkedModelSerializer when you think that it is more convenient for the API consumer to have related items right away instead of making additional requests to retrieve them.

Nested representations can be implemented via the Meta.depth option or by using the related model's serializer instead of a RelatedField.

As @xleon said in his comment using URLs as keys makes it easier for other developers to understand your API.

Ploy answered 29/10, 2015 at 21:0 Comment(1)
Nice answer, I would add just one thing: using hyperlinks in your resources will make it easier for any developer using your web API. If they can see the whole resource URI they won´t need any documentation or other ways to find that outNo
S
105

We need to implement relationship between entities in Web API design. There are several ways to do that (as mentions on DRF documentation):

  • Using primary keys.
  • Using hyperlinking between entities.
  • Using a unique identifying slug field on the related entity.
  • Using the default string representation of the related entity.
  • Nesting the related entity inside the parent representation.
  • Some other custom representation

The HyperlinkedModelSerializer has the following differences from ModelSerializer:

  • It does not include the id field by default.
  • It includes a url field, using HyperlinkedIdentityField.
  • Relationships use HyperlinkedRelatedField, instead of PrimaryKeyRelatedField.

A simple example:

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:yourpassword 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"
        }
    ]

But if you change

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

The result will be:

   "results": [
        {
            "email": "[email protected]",
            "groups": [
                1,
                2
            ],
            "url": "http://127.0.0.1:8000/users/1/",
            "username": "admin"
        }
    ]
Spark answered 22/9, 2017 at 4:27 Comment(0)
P
72

The only difference is, as in citation you included, that primary and foreign keys are represented by URLs that point to those resources, instead of just actual key values.

The benefit is that you will not have to construct resource URLs in your frontend when you want to retrieve related objects.

Another thing entirely is nested representations which allows you to inline related objects in your serializer output. This can be combined with both ModelSerializer and HyperlinkedModelSerializer when you think that it is more convenient for the API consumer to have related items right away instead of making additional requests to retrieve them.

Nested representations can be implemented via the Meta.depth option or by using the related model's serializer instead of a RelatedField.

As @xleon said in his comment using URLs as keys makes it easier for other developers to understand your API.

Ploy answered 29/10, 2015 at 21:0 Comment(1)
Nice answer, I would add just one thing: using hyperlinks in your resources will make it easier for any developer using your web API. If they can see the whole resource URI they won´t need any documentation or other ways to find that outNo
G
11

One cost of HyperlinkedModelSerializers that should be noted is that if your API supports filtering or ordering via query parameters in the URL it is a bit more difficult for your frontend consumer to use the hyperlinked url fields for constructing query params because they have to parse out the pk from the URL rather than having the pk directly available.

For example, assuming an object on a route at /api/objects/12/ the consumer would need to parse the url field to extract the 12 in order to construct a query filtering by this object on another endpoint: /api/otherobjects/?object=12. Not a huge problem, but a bummer if you plan on doing lots of filtering.

Goring answered 6/3, 2018 at 19:19 Comment(1)
Easy solution to this is adding the 'id' field too in your serializer: id = serializers.ReadOnlyField()Katlin
T
0

The HyperlinkedModelSerializer class is similar to the ModelSerializer class except that it uses hyperlinks to represent relationships, rather than primary keys.

By default, the serializer will include a URL field instead of a primary key field.

The URL field will be represented using a HyperlinkedIdentityField serializer field, and any relationships on the model will be represented using a HyperlinkedRelatedField serializer field.

Tetragram answered 12/3 at 12:45 Comment(1)
Thanks you for contributing to the site through editing other's posts. However, please go through the list of edits you've suggested. Most have been rejected or should've been rejected (I have revised most of them by now). The main thing you seem to be doing is adding irrelevant bold and italic formatting, which, as this example shows, does nothing for the readability of the post and just makes for annoyed readers. Read How does editing work? on what a good edit consists of.Rento

© 2022 - 2024 — McMap. All rights reserved.