Jeff Schenck - The REST Ascendancy

Jeff Schenck - The REST Ascendancy

As frontend web frameworks like AngularJS and Backbone.js take over, is Python on the server destined to be demoted to a basic REST interface? If we embrace our new JavaScript overlords, how do we ensure Python is best positioned for this new world of REST on the server?

https://us.pycon.org/2015/schedule/presentation/423/

D5710b3bca38f1233274b4cbc523dc4b?s=128

PyCon 2015

April 18, 2015
Tweet

Transcript

  1. The REST Ascendancy

  2. The REST Ascendancy OUTLINE 1. WHY REST 2. BEST OF

    THE REST 3. PAIN POINTS 4. THE FUTURE
  3. The REST Ascendancy 1. WHY REST 2. STATE OF REST

    3. PAIN POINTS 4. THE FUTURE
  4. The REST Ascendancy

  5. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Frontend Backend
  6. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Frontend Backend HTML!
  7. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Frontend Backend HTML! and AJAX!
  8. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Frontend Backend
  9. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Frontend Backend Representational State Transfer!
  10. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Frontend Backend REST!
  11. The REST Ascendancy 2. STATE OF REST 1. WHY REST

    3. PAIN POINTS 4. THE FUTURE
  12. The REST Ascendancy Django REST Framework 172,000 downloads Django Tastypie

    37,000 downloads Django Piston 4,000 downloads Flask RESTful 60,000 downloads Pyramid Cornice 12,000 downloads
  13. The REST Ascendancy SERIALIZERS class CatSerializer(serializers.ModelSerializer): class Meta: model =

    Cat fields = ['id', 'age', 'hair', 'grumpiness',]
  14. The REST Ascendancy VIEWS class CatViewSet(viewsets.ModelViewSet): queryset = Cat.objects.all() serializer_class

    = CatSerializer
  15. The REST Ascendancy PERMISSIONS class OwnerOrReadOnlyPermission(permissions.BasePermission): def has_object_permission(self, request, view,

    obj): if request.method in permissions.SAFE_METHODS: return True return obj.owner == request.user
  16. The REST Ascendancy 3. PAIN POINTS 1. WHY REST 2.

    STATE OF REST 4. THE FUTURE
  17. The REST Ascendancy WHO’S THE CONSUMER? Your API

  18. The REST Ascendancy WHO’S THE CONSUMER? Your API Developers

  19. The REST Ascendancy WHO’S THE CONSUMER? Your API Your App

    Developers
  20. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Frontend Backend
  21. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Frontend Backend
  22. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Untrusted Trusted
  23. The REST Ascendancy • Database • Cache • App logic

    • Display logic • Interactions Untrusted Trusted
  24. The REST Ascendancy AUTHENTICATION

  25. The REST Ascendancy AUTHENTICATION • Session auth 'rest_framework.authentication.SessionAuthentication'

  26. The REST Ascendancy AUTHENTICATION • Session auth • Token auth

    example.com/api/products/? jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3O DkwIiwibmFtZSI6IkpvaG4gRG9lIDIiLCJhZG1pbiI6dHJ1ZX0.wUJs5ArG9be wMeW3mZONhhAGs877ZWJWZlMHlROTyKU
  27. The REST Ascendancy AUTHENTICATION • Session auth • Token auth

    • Signed auth example.com/api/products/? sign=svf668fe0d-a2ab-4855-bb65-baf210b1e64c:bZyPId_-Qmi5B- YUkifs5FLEqqI
  28. The REST Ascendancy AUTHENTICATION • Session auth • Token auth

    • Signed auth • All the things!
  29. The REST Ascendancy PERMISSIONS

  30. The REST Ascendancy PERMISSIONS • Table-level permissions

  31. The REST Ascendancy PERMISSIONS • Table-level permissions • Column-level permissions

  32. The REST Ascendancy PERMISSIONS • Table-level permissions • Column-level permissions

    • Row-level permissions
  33. The REST Ascendancy PERMISSIONS • Table-level permissions • Column-level permissions

    • Row-level permissions • Read vs write permissions
  34. The REST Ascendancy PERMISSIONS • Table-level permissions • Column-level permissions

    • Row-level permissions • Read vs write permissions • Multiple simultaneous auth methods
  35. The REST Ascendancy PERMISSIONS • Table-level permissions • Column-level permissions

    • Row-level permissions • Read vs write permissions • Multiple simultaneous auth methods • All the things!
  36. The REST Ascendancy REAL EXAMPLE

  37. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): queryset =

    Order.objects.all() permission_classes = [ Or( And(IsOrganizationMember, IsReadOnly), And(IsOrganizationAdmin, patch_fields_factory()), IsVendorAdmin, And(SignedObjectActionPermission, IsReadOnly), IsAdminUser, ) ] ...
  38. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): queryset =

    Order.objects.all() permission_classes = [ Or( And(IsOrganizationMember, IsReadOnly), And(IsOrganizationAdmin, patch_fields_factory()), IsVendorAdmin, And(SignedObjectActionPermission, IsReadOnly), IsAdminUser, ) ] ...
  39. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): queryset =

    Order.objects.all() permission_classes = [ Or( And(IsOrganizationMember, IsReadOnly), And(IsOrganizationAdmin, patch_fields_factory()), IsVendorAdmin, And(SignedObjectActionPermission, IsReadOnly), IsAdminUser, ) ] ...
  40. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): queryset =

    Order.objects.all() permission_classes = [ Or( And(IsOrganizationMember, IsReadOnly), And(IsOrganizationAdmin, patch_fields_factory()), IsVendorAdmin, And(SignedObjectActionPermission, IsReadOnly), IsAdminUser, ) ] ...
  41. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): queryset =

    Order.objects.all() permission_classes = [ Or( And(IsOrganizationMember, IsReadOnly), And(IsOrganizationAdmin, patch_fields_factory()), IsVendorAdmin, And(SignedObjectActionPermission, IsReadOnly), IsAdminUser, ) ] ...
  42. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): queryset =

    Order.objects.all() permission_classes = [ Or( And(IsOrganizationMember, IsReadOnly), And(IsOrganizationAdmin, patch_fields_factory()), IsVendorAdmin, And(SignedObjectActionPermission, IsReadOnly), IsAdminUser, ) ] ...
  43. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): queryset =

    Order.objects.all() permission_classes = [ Or( And(IsOrganizationMember, IsReadOnly), And(IsOrganizationAdmin, patch_fields_factory()), IsVendorAdmin, And(SignedObjectActionPermission, IsReadOnly), IsAdminUser, ) ] ...
  44. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): queryset =

    Order.objects.all() permission_classes = [ Or( And(IsOrganizationMember, IsReadOnly), And(IsOrganizationAdmin, patch_fields_factory()), IsVendorAdmin, And(SignedObjectActionPermission, IsReadOnly), IsAdminUser, ) ] ...
  45. The REST Ascendancy REAL EXAMPLE

  46. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): ... def

    get_queryset(self): queryset = super(OrderViewSet, self).get_queryset() if self.request.user.is_authenticated(): if self.request.user.is_staff: return self.queryset return self.queryset.filter( Q(organization__accounts=self.request.user) | Q(vendor__accounts=self.request.user), is_visible=True, ).distinct() return queryset.none()
  47. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): ... def

    get_queryset(self): queryset = super(OrderViewSet, self).get_queryset() if self.request.user.is_authenticated(): if self.request.user.is_staff: return self.queryset return self.queryset.filter( Q(organization__accounts=self.request.user) | Q(vendor__accounts=self.request.user), is_visible=True, ).distinct() return queryset.none()
  48. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): ... def

    get_queryset(self): queryset = super(OrderViewSet, self).get_queryset() if self.request.user.is_authenticated(): if self.request.user.is_staff: return self.queryset return self.queryset.filter( Q(organization__accounts=self.request.user) | Q(vendor__accounts=self.request.user), is_visible=True, ).distinct() return queryset.none()
  49. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): ... def

    get_queryset(self): queryset = super(OrderViewSet, self).get_queryset() if self.request.user.is_authenticated(): if self.request.user.is_staff: return self.queryset return self.queryset.filter( Q(organization__accounts=self.request.user) | Q(vendor__accounts=self.request.user), is_visible=True, ).distinct() return queryset.none()
  50. The REST Ascendancy REAL EXAMPLE class OrderViewSet(SignViewSetMixin, viewsets.ModelViewSet): ... def

    get_queryset(self): queryset = super(OrderViewSet, self).get_queryset() if self.request.user.is_authenticated(): if self.request.user.is_staff: return self.queryset return self.queryset.filter( Q(organization__accounts=self.request.user) | Q(vendor__accounts=self.request.user), is_visible=True, ).distinct() return queryset.none()
  51. The REST Ascendancy REAL EXAMPLE — LIBRARIES • Django REST

    Framework
  52. The REST Ascendancy REAL EXAMPLE — LIBRARIES • Django REST

    Framework • rest_condition (forked)
  53. The REST Ascendancy REAL EXAMPLE — LIBRARIES • Django REST

    Framework • rest_condition (forked) • signed viewsets (in-house)
  54. The REST Ascendancy REAL EXAMPLE — LIBRARIES • Django REST

    Framework • rest_condition (forked) • signed viewsets (in-house) • patch fields factory (in-house)
  55. The REST Ascendancy REAL EXAMPLE — CODE LOCATIONS • ViewSet

    class mixin
  56. The REST Ascendancy REAL EXAMPLE — CODE LOCATIONS • ViewSet

    class mixin • ViewSet permissions list
  57. The REST Ascendancy REAL EXAMPLE — CODE LOCATIONS • ViewSet

    class mixin • ViewSet permissions list • ViewSet get_queryset method
  58. The REST Ascendancy REAL EXAMPLE — CODE LOCATIONS • ViewSet

    class mixin • ViewSet permissions list • ViewSet get_queryset method • Serializer fields (not depicted)
  59. The REST Ascendancy REAL EXAMPLE — CODE LOCATIONS • ViewSet

    class mixin • ViewSet permissions list • ViewSet get_queryset method • Serializer fields (not depicted) • Permission classes (not depicted)
  60. The REST Ascendancy 4. THE FUTURE 1. WHY REST 2.

    STATE OF REST 3. PAIN POINTS
  61. The REST Ascendancy EMBETTERMENT • Better tokens and signed URLs

  62. The REST Ascendancy EMBETTERMENT • Better tokens and signed URLs

    • Combined list/object permissions
  63. The REST Ascendancy EMBETTERMENT • Better tokens and signed URLs

    • Combined list/object permissions • Permission organization
  64. None
  65. The REST Ascendancy Jeff Schenck CTO & Co-Founder twitter @jeffschenck

    email jeff@chewse.com