APIS with Django Rest Framework So easy, you can learn it in 25 minutes. (No, seriously)
REST Describes an architecture For the purpose of web apis: - stateless - support common HTTP methods - return internet media type (JSON or XML…)
HTTP Verbs POST, GET, (PUT, PATCH), DELETE Like CRUD… sort of.
What do REST endpoints look like? /api/users/ - GET will return a collection of all users /api/users/<id> - GET will return a single user
Common HTTP Response Codes 200 - OK 201 - Created 401 - Not Authorized 404 - Not Found 500 - Server Error
Idempotency Is a hard to pronounce word. The operation will produce the same result, no matter how many times it is repeated. PUT, DELETE - Idempotent. GET - Safe method. Produces no side effects.
Where DRF Comes in It makes REST API creation easy!
Serializers
A Model class Tweet(models.Model): user = models.ForeignKey(User) text = models.CharField(max_length=140) timestamp = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-timestamp']
And a ModelSerializer class TweetSerializer(serializers.ModelSerializer): user = serializers.Field(source='user') class Meta: model = Tweet fields = ('text', 'user', 'timestamp')
The Result [ { "text": "Bob is the coolest name EVAR", "user": "bob", "timestamp": "2014-08-29T18:51:19Z" } ]
Validation
Field Validation def validate_text(self, attrs, source): value = attrs[source] if len(value) < 5: raise serializers.ValidationError( "Text is too short!") return attrs
Permissions
Permissions IsAuthenticated - Only allow authenticated Users IsAdminUser - user.is_staff is True class IsAuthorOrReadOnly(permissions.BasePermission): def has_object_permission(self, request, view, obj): if request.method in permissions.SAFE_METHODS: return True return obj.user == request.user
Views
ModelViewSets class TweetViewSet(viewsets.ModelViewSet): queryset = Tweet.objects.all() serializer_class = TweetSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsAuthorOrReadOnly,) def pre_save(self, obj): obj.user = self.request.user
Generic Views APIView is base class. Takes care of routing. Mixins provide common operations, and generic Views provide common combinations of mixins. ex: ListCreateAPIView, UpdateAPIView
Requests
Requests The DRF Request provides many methods we are used to seeing. request.DATA is similar to request.POST It handles data types we specified, and is available on all requests.
Responses
Responses DRF Responses are unrendered. Return DATA, and status code. Behind the scenes: serializer = TweetSerializer(tweets, many=True) return Response(serializer.data)
Routing
ViewSet Routing router = DefaultRouter() router.register(r'tweets', views.TweetViewSet) router.register(r'users', views.UserViewSet) urlpatterns = patterns('', url(r'^api/', include(router.urls)) )
Browsable API
Unit Testing
Does our validation work? def test_create_invalid_tweet(self): self.client = APIClient() self.client.login(username='bob', password='bob') url = reverse('tweet-list') data = {'text': "x" * 4} response = self.client.post(url, data, format='json') error_msg = response.data['text'][0] self.assertEquals(response.status_code, 400) self.assertEquals(error_msg, 'Text is too short!')
When to use it? New projects. - You don’t have to code for the framework, but it’s easier to integrate. Clean models.
When to be cautious (IMHO) Complex models, tons of interdependent validation logic, dealing with saving non- model fields on a model Legacy Django… It’s out there.
Doesn’t mean you shouldn’t go for it it, but prepare for hurdles.
Next Steps pip install djangorestframework Also, the documentation rocks. http://www.django-rest-framework.org/
Bye Everybody! @nnja

Djangocon 2014 - Django REST Framework - So Easy You Can Learn it in 25 Minutes

  • 1.
    APIS with Django Rest Framework Soeasy, you can learn it in 25 minutes. (No, seriously)
  • 2.
    REST Describes an architecture Forthe purpose of web apis: - stateless - support common HTTP methods - return internet media type (JSON or XML…)
  • 3.
    HTTP Verbs POST, GET,(PUT, PATCH), DELETE Like CRUD… sort of.
  • 4.
    What do RESTendpoints look like? /api/users/ - GET will return a collection of all users /api/users/<id> - GET will return a single user
  • 5.
    Common HTTP ResponseCodes 200 - OK 201 - Created 401 - Not Authorized 404 - Not Found 500 - Server Error
  • 6.
    Idempotency Is a hardto pronounce word. The operation will produce the same result, no matter how many times it is repeated. PUT, DELETE - Idempotent. GET - Safe method. Produces no side effects.
  • 7.
    Where DRF Comesin It makes REST API creation easy!
  • 8.
  • 9.
    A Model class Tweet(models.Model): user= models.ForeignKey(User) text = models.CharField(max_length=140) timestamp = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-timestamp']
  • 10.
    And a ModelSerializer classTweetSerializer(serializers.ModelSerializer): user = serializers.Field(source='user') class Meta: model = Tweet fields = ('text', 'user', 'timestamp')
  • 11.
    The Result [ { "text": "Bobis the coolest name EVAR", "user": "bob", "timestamp": "2014-08-29T18:51:19Z" } ]
  • 12.
  • 13.
    Field Validation def validate_text(self,attrs, source): value = attrs[source] if len(value) < 5: raise serializers.ValidationError( "Text is too short!") return attrs
  • 14.
  • 15.
    Permissions IsAuthenticated - Onlyallow authenticated Users IsAdminUser - user.is_staff is True class IsAuthorOrReadOnly(permissions.BasePermission): def has_object_permission(self, request, view, obj): if request.method in permissions.SAFE_METHODS: return True return obj.user == request.user
  • 16.
  • 17.
    ModelViewSets class TweetViewSet(viewsets.ModelViewSet): queryset =Tweet.objects.all() serializer_class = TweetSerializer permission_classes = (permissions.IsAuthenticatedOrReadOnly, IsAuthorOrReadOnly,) def pre_save(self, obj): obj.user = self.request.user
  • 18.
    Generic Views APIView isbase class. Takes care of routing. Mixins provide common operations, and generic Views provide common combinations of mixins. ex: ListCreateAPIView, UpdateAPIView
  • 19.
  • 20.
    Requests The DRF Requestprovides many methods we are used to seeing. request.DATA is similar to request.POST It handles data types we specified, and is available on all requests.
  • 21.
  • 22.
    Responses DRF Responses areunrendered. Return DATA, and status code. Behind the scenes: serializer = TweetSerializer(tweets, many=True) return Response(serializer.data)
  • 23.
  • 24.
    ViewSet Routing router =DefaultRouter() router.register(r'tweets', views.TweetViewSet) router.register(r'users', views.UserViewSet) urlpatterns = patterns('', url(r'^api/', include(router.urls)) )
  • 25.
  • 28.
  • 29.
    Does our validationwork? def test_create_invalid_tweet(self): self.client = APIClient() self.client.login(username='bob', password='bob') url = reverse('tweet-list') data = {'text': "x" * 4} response = self.client.post(url, data, format='json') error_msg = response.data['text'][0] self.assertEquals(response.status_code, 400) self.assertEquals(error_msg, 'Text is too short!')
  • 30.
    When to useit? New projects. - You don’t have to code for the framework, but it’s easier to integrate. Clean models.
  • 31.
    When to becautious (IMHO) Complex models, tons of interdependent validation logic, dealing with saving non- model fields on a model Legacy Django… It’s out there.
  • 32.
    Doesn’t mean youshouldn’t go for it it, but prepare for hurdles.
  • 33.
    Next Steps pip installdjangorestframework Also, the documentation rocks. http://www.django-rest-framework.org/
  • 34.