Creating an endpoint for the root of our API
Right now we have endpoints for ‘snippets’ and ‘users’, but we don’t have a single entry point to our API. To create one, we’ll use a regular function-based view and the@api_view decorator we introduced earlier.
In your snippets/views.py add:
snippets/views.py
reverse function in order to return fully-qualified URLs; second, URL patterns are identified by convenience names that we will declare later on in our snippets/urls.py.
Creating an endpoint for the highlighted snippets
The other obvious thing that’s still missing from our pastebin API is the code highlighting endpoints. Unlike all our other API endpoints, we don’t want to use JSON, but instead just present an HTML representation. There are two styles of HTML renderer provided by REST framework, one for dealing with HTML rendered using templates, the other for dealing with pre-rendered HTML. The second renderer is the one we’d like to use for this endpoint. The other thing we need to consider when creating the code highlight view is that there’s no existing concrete generic view that we can use. We’re not returning an object instance, but instead a property of an object instance. Instead of using a concrete generic view, we’ll use the base class for representing instances, and create our own.get() method. In your snippets/views.py add:
snippets/views.py
snippets/urls.py:
snippets/urls.py
snippets/urls.py
Hyperlinking our API
Dealing with relationships between entities is one of the more challenging aspects of Web API design. There are a number of different ways that we might choose to represent a relationship:Primary Keys
Simple numeric IDs that reference related objects.
Hyperlinking
URLs that point to related resources (recommended).
Slug Fields
Unique identifying slug field on the related entity.
String Representation
Default string representation of the related entity.
Nested Relations
Nested entities inside the parent representation.
Custom Representation
Some other custom representation.
HyperlinkedModelSerializer instead of the existing ModelSerializer.
HyperlinkedModelSerializer vs ModelSerializer
TheHyperlinkedModelSerializer has the following differences from ModelSerializer:
We can easily re-write our existing serializers to use hyperlinking. In your
snippets/serializers.py add:
snippets/serializers.py
'highlight' field. This field is of the same type as the url field, except that it points to the 'snippet-highlight' url pattern, instead of the 'snippet-detail' url pattern.
Because we’ve included format suffixed URLs such as '.json', we also need to indicate on the highlight field that any format suffixed hyperlinks it returns should use the '.html' suffix.
Making sure our URL patterns are named
If we’re going to have a hyperlinked API, we need to make sure we name our URL patterns. Let’s take a look at which URL patterns we need to name:- The root of our API refers to
'user-list'and'snippet-list'. - Our snippet serializer includes a field that refers to
'snippet-highlight'. - Our user serializer includes a field that refers to
'snippet-detail'. - Our snippet and user serializers include
'url'fields that by default will refer to'{model_name}-detail', which in this case will be'snippet-detail'and'user-detail'.
snippets/urls.py file should look like this:
snippets/urls.py
Adding pagination
The list views for users and code snippets could end up returning quite a lot of instances, so really we’d like to make sure we paginate the results, and allow the API client to step through each of the individual pages. We can change the default list style to use pagination, by modifying ourtutorial/settings.py file slightly. Add the following setting:
tutorial/settings.py
REST_FRAMEWORK, which helps keep them well separated from your other project settings.
We could also customize the pagination style if we needed to, but in this case we’ll just stick with the default.
Pagination Styles
REST framework includes several pagination styles:PageNumberPagination
PageNumberPagination
Standard page number based pagination. Supports
?page=2 style queries.LimitOffsetPagination
LimitOffsetPagination
Limit and offset based pagination. Supports
?limit=10&offset=20 style queries.CursorPagination
CursorPagination
Cursor based pagination. More complex but provides consistent pagination even when items are being added/removed.
Browsing the API
If we open a browser and navigate to the browsable API, you’ll find that you can now work your way around the API simply by following links. You’ll also be able to see the ‘highlight’ links on the snippet instances, that will take you to the highlighted code HTML representations.Benefits of Hyperlinked APIs
Discoverability
Clients can navigate the API by following links, making it self-documenting.
Decoupling
URLs can change without breaking clients, as long as the link relations remain the same.
Standards-based
Follows REST principles and HATEOAS (Hypermedia as the Engine of Application State).
Developer-friendly
The browsable API becomes much more useful when you can click through relationships.
