0% found this document useful (0 votes)
84 views

Building Apis With Django Rest Framework: Timothy Liu, VP Engineering

This document discusses building APIs with Django REST Framework. It covers core concepts like routers, serializers, and viewsets that map HTTP verbs to view methods. It also discusses more advanced topics like custom endpoints, querysets, authentication, permissions, pagination, and rate limiting. The goal is to demonstrate how DRF allows creating RESTful APIs that expose resources and CRUD operations through standard HTTP verbs and responses.

Uploaded by

pavan kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
84 views

Building Apis With Django Rest Framework: Timothy Liu, VP Engineering

This document discusses building APIs with Django REST Framework. It covers core concepts like routers, serializers, and viewsets that map HTTP verbs to view methods. It also discusses more advanced topics like custom endpoints, querysets, authentication, permissions, pagination, and rate limiting. The goal is to demonstrate how DRF allows creating RESTful APIs that expose resources and CRUD operations through standard HTTP verbs and responses.

Uploaded by

pavan kumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 20

Building APIs with

Django REST Framework

Timothy Liu, VP Engineering


@timothytliu
Cloud CRM Calendar Chat
Storage
Users Developer's App
Outline
● Core DRF Concepts
● REST: Richardson Maturity Model
○ Level 0: HTTP requests (+JSON response)
○ Level 1: Resources
○ Level 2: HTTP Verbs
● Advanced DRF Concepts
● Questions
READ requests
Core Concepts
Filter QuerySet

Authentication WRITE requests


Request Parser
Routers Check De-serialize
Permissions Request Data
Versions
Response Renderer Validate Data
Rate-limiting

Response
Check Obj. Perms

Paginate Data

Serialize
Response
REST: HTTP request and response (w/ JSON)

curl -H "Content-Type: application/json"


-H "Authorization: Bearer TOKEN"
-X POST -d '{"name": "hello"}'
"https://api.server.com/v1/accounts"

{
"id": 123
}
REST: Resources

"https://api.server.com/v1/accounts"

Add URLs directly to urlpatterns.


A Router generates API endpoint URLs based on resources*

*URLs in urlpatterns can also route to DRF views directly, similar to in Django
REST: Resources

"https://api.server.com/v1/accounts"

Each route corresponds to a view method


Each route corresponds to a view method in a ViewSet class
ViewSets: HTTP Verbs View
methods
HTTP Verb ViewSet Method

.list()
GET .retrieve()

POST .create()

PUT .update()

PATCH .partial_update()

DELETE .destroy()
READ requests ViewSets: Class-based Views
● Routers map to actions. Defaults available for Django models.

● Serializers convert queryset data to/from JSON data.

class AccountViewSet(viewsets.ViewSet):
"""A simple ViewSet for listing or retrieving Accounts."""

def list(self, request):


queryset = Account.objects.all()
serializer = AccountSerializer(queryset, many=True)
return Response(serializer.data)
def retrieve(self, request, pk=None):
queryset = Account.objects.all()
account = get_object_or_404(queryset, pk=pk)
serializer = AccountSerializer(account)
return Response(serializer.data)

django-rest-framework.org/api-guide/viewsets
READ requests ViewSets: Using QuerySets
Filter QuerySet ● Query the database.

● Filter the QuerySet returned.

from rest_framework import filters, viewsets

class IsOwnerFilterBackend(filters.BaseFilterBackend):
"""Filter that only allows users to see their own objects."""
def filter_queryset(self, request, queryset, view):
return queryset.filter(owner=request.user)
class AccountViewSet(viewsets.ModelViewSet):
"""A simple ViewSet for searching owned accounts: GET /accounts?email=kloudless"""
queryset = Account.objects.all()
serializer = AccountSerializer

filter_backends = [filters.SearchFilter, IsOwnerFilterBackend]


search_fields = ['email']
django-rest-framework.org/api-guide/filtering
WRITE requests
Serializers and Models
De-serialize
Request Data ● DRY: Use a Model Serializer
Validate Data
● Validate before model validation

from rest_framework import serializers

class AccountSerializer(serializers.ModelSerializer):
class Meta:
model = Account
fields = ['id', 'name', 'custom_properties']

def validate(self, data):


if len(data['custom_properties']) > 5:
raise serializers.ValidationError("custom_properties exceed 5")
return data

def create(self, validated_data):


return Account.objects.create(**validated_data)
Response
Check Obj. Perms
Pagination
Paginate Data ● Use default or define custom pagination

Serialize ● Serialize response data for list() or ListModelMixin()


Response

class CustomPagination(pagination.PageNumberPagination):
def get_paginated_response(self, data):
return Response({
'links': {
'next': self.get_next_link(),
'previous': self.get_previous_link()
},
'count': self.page.paginator.count,
'results': data
})

class AccountViewSet(viewsets.ModelViewSet):
pagination_class = CustomPagination
REST: HTTP request and response (w/
Authentication
JSON)
Check
Permissions

Rate-limiting

curl -H "Content-Type: application/json"


-H "Authorization: Bearer TOKEN"
-X POST -d '{"name": "hello"}'
"https://api.server.com/v1/accounts"

429 Too Many Requests


Authentication Authentication: Identifying Users
Check ● Associate request with user
Permissions
● Handle different authorization schemes
Rate-limiting

from rest_framework import authentication

class TokenAuthentication(authentication.BaseAuthentication):
def authenticate(self, request):
token = authentication.get_authorization_header(request).partition(' ')[-1]

try:
user = User.objects.get(token__key=token)
except User.DoesNotExist:
raise exceptions.AuthenticationFailed('No such user')

return (user, token)


django-rest-framework.org/api-guide/authentication
Authentication Checking User Permissions
Check ● Check access to this view for any request
Permissions
● Check access to retrieve, update, or delete a specific object
Rate-limiting

from rest_framework import permissions

class IsOwnerForModification(permissions.BasePermission):
"""Only allow write access to the object's owner"""
def has_object_permission(self, request, view, obj):
# GET, HEAD, OPTIONS allowed
if request.method in permissions.SAFE_METHODS:
return True

return obj.owner == request.user

django-rest-framework.org/api-guide/permissions
Authentication Rate-limiting User Requests
Check ● Per-user throttles: Burst (e.g. 10/s), Sustained (e.g. 10,000/day)
Permissions
● Can be scoped per View, or include custom throttling like below.
Rate-limiting

from rest_framework import throttling

class CosmicRayRateThrottle(throttling.BaseThrottle):
"""Simulate a stray cosmic ray flipping a bit that rate-limits this request"""
def allow_request(self, request, view):
return random.randint(1, 10e12) == 1

django-rest-framework.org/api-guide/throttling
READ requests
Advanced Concepts
Filter QuerySet

Authentication WRITE requests


Request Parser
Routers Check De-serialize
Permissions Request Data
Versions
Response Renderer Validate Data
Rate-limiting

Response
Check Obj. Perms

Paginate Data

Serialize
Response
Custom Endpoints and QuerySets
● DRF allows custom routes and view methods

● Return custom JSON response based on the upstream service

class KloudlessFileQuerySet(object):
def copy(self, *args, **kwargs):
... # copy file in cloud service

class CustomFileViewSet(viewsets.ViewSet):
queryset = KloudlessFileQuerySet()

@action(detail=True, methods=['post'])
def copy(self, request):
queryset = self.filter_queryset(self.get_queryset())

obj = queryset.copy(self.lookup, **params)

return response.Response(self.get_serializer(obj).data, status=201)


Thanks
@timothytliu

You might also like