Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Обзор и сравнение методов реализации REST API в django

Обзор и сравнение методов реализации REST API в django

Посмотрим на различные библиотеки и способы реализации API, постараемся их сравнить.

53b0434aded1fb944ec3037c382158c1?s=128

Moscow Python Meetup
PRO

June 24, 2015
Tweet

Transcript

  1. Как и ожидалось, мой Django REST API не удался

  2. Зачем? клиент(js, android, ...) <-> сервер(django)

  3. Как? REST(Representational State Transfer) • Клиент-серверная архитектура. • Сервер не

    обязан сохранять информацию о состоянии клиента. • В каждом запросе клиента должно явно содержаться указание о возможности кэширования ответа и получения ответа из существующего кэша. • Клиент может взаимодействовать не напрямую с сервером, а с произвольным количеством промежуточных узлов. • Унифицированный программный интерфейс сервера. URI в качестве запросов к серверу. Ответы в JSON, XML.
  4. class ApiDetailView(View): def get(self, request, *args, **kwargs): serialized_data = CustomSerializer().serialize([obj])

    return JsonResponse(data=serialized_data[0], safe=False) def delete(self, request, *args, **kwargs): def put(self, request, *args, **kwargs): if form.is_valid(): class ApiListView(View): def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): if form.is_valid(): Django
  5. class ApiDetailView(View): def get(self, request, *args, **kwargs): serialized_data = CustomSerializer().serialize([obj])

    return JsonResponse(data=serialized_data[0], safe=False) def delete(self, request, *args, **kwargs): def put(self, request, *args, **kwargs): if form.is_valid(): class ApiListView(View): def get(self, request, *args, **kwargs): def post(self, request, *args, **kwargs): if form.is_valid(): Django Один ресурс, но два класса с дублируемой логикой
  6. class EntryListApiView(ApiListView): model = Entry form = EntryForm class EntryDetailApiView(ApiDetailView):

    model = Entry form = EntryForm url(r'entry/$', EntryListApiView.as_view()), url(r'entry/(?P<pk>\d+)/$', EntryDetailApiView.as_view()),
  7. class EntryListApiView(ApiListView): model = Entry form = EntryForm class EntryDetailApiView(ApiDetailView):

    model = Entry form = EntryForm url(r'entry/$', EntryListApiView.as_view()), url(r'entry/(?P<pk>\d+)/$', EntryDetailApiView.as_view()), Дублирование Один ресурс два патерна
  8. • сериализация/десериализация • доступные методы(GET, POST) • работа со связями

    • регистрация патернов для ссылок • гибкость и расширяемость • валидация • фильтрация • ... Нужна архитектура но это сложно
  9. Что есть? https://www.djangopackages.com/grids/g/rest/

  10. обновления django 1.8 python3 версия tastypie 04.2015 1.5+ 0.12.1* django-rest-framework

    06.2015 1.4.2+ 3.1.2 restless 06.2015 1.5+ 2.0.1 django-nap 05.2015 1.4-1.7 0.14.4
  11. https://github.com/overmesgit/django_rest_api_comparison

  12. API CRUD для class Entry(models.Model): user = models.ForeignKey(User) title =

    models.CharField(max_length=400) created_date = models.DateTimeField (auto_now_add=True) content = models.TextField()
  13. Критерии • поддержка и развитие • работа с django •

    архитектура • документация
  14. None
  15. class EntryResource(ModelResource): user = fields.ForeignKey(UserResource, 'user') class Meta: queryset =

    Entry.objects.all() resource_name = 'entry' authorization = Authorization() validation = EntryValidator(form_class=EntryForm) api_urls = EntryResource().urls
  16. Плюсы • framework • монолитный • подробная документация • много

    сторонних библиотек
  17. Минусы • монолитный • не развивается • документация плохо структурирована

    • сложности с валидацией
  18. None
  19. class EntrySerializer(serializers.HyperlinkedModelSerializer): class Meta: model = Entry class EntryViewSet(viewsets.ModelViewSet): queryset

    = Entry.objects.all() serializer_class = EntrySerializer router = routers.DefaultRouter() router.register(r'entry', EntryViewSet)
  20. Плюсы • framework • модульная архитектура • веб просмотр •

    хорошая документация • много сторонних библиотек • хорошая валидация • активно развивается • хороший код
  21. Tom Christie http://www.django-rest-framework.org/topics/3.0-announcement/

  22. Минусы • много сущностей • хорошо структурированная, но запутанная документация

    • 2 -> 3, нет обратной совместимости
  23. TastyPie и RestFramework • генерируют API из моделей • генерируют

    паттерны для ссылок • не только Django Model • пагинация • авторизация • аутентификация • кэширование • ограничение запросов(Throttling) • фильтрация • JSON, JSONP, XML, YAML Плотность и Вложенность
  24. Валидация TastyPie RestFramework

  25. Django Content Types TastyPie RestFramework

  26. Связи ресурсов TastyPie RestFramework

  27. Поиск связей TastyPie RestFramework

  28. Расширяемость TastyPie RestFramework

  29. Web view TastyPie RestFramework

  30. Развитие TastyPie RestFramework

  31. Tastypie проще, но сложнее изменять RestFramework сложнее, но проще изменять

  32. Restless https://github.com/toastdriven/restless/ class MyList(ListEndpoint): model = Entry class MyDetail(DetailEndpoint): model

    = Entry url(r'entry/$', MyList.as_view(), name='entry-list-restless'), url(r'entry/(?P<pk>\d+)/$', MyDetail.as_view(), name='entry-detail-restless'),
  33. Плюсы • хорошая документация • простой • придерживается философии •

    Django, Flask, Pyramid & Itty • есть пакет для Django • валидация • интересный сериализатор
  34. serialize(author, include=[ ('books', dict( # поля для каждой книги fields=[

    'title', 'isbn', ('reviews', dict()) # получить список всех reviews ] )), ('average_rating', # добавление поля lambda a: a.books.all().aggregate(Avg('rating'))['avg_rating']) ])
  35. Минусы • отсутствуют связи между представлениями • только архитектура

  36. Django-nap class EntrySerialiser(serialiser.ModelSerialiser): def object_inflate(self, data, instance=None, **kwargs): def deflate_user(self,

    obj, data, **kwargs): def inflate_user(self, data, obj, instance, **kwargs): class Meta: model = Entry class EntryPublisher(ObjectDeleteMixin, rest.ModelPublisher): api_name = 'entry' serialiser = EntrySerialiser() def object_delete_default(self, request, object_id, **kwargs): def object_put_default(self, request, object_id, **kwargs): https://github.com/funkybob/django-nap/
  37. Плюсы • модульный • простой

  38. Минусы • плохая документация • только get, get list, post

    • запутанный
  39. Скорость

  40. None
  41. Спасибо команде DjangoMoscowMeetup: Илья Барышев Григорий Петров Владимир Филонов Валентин

    Домбровский письма overmes@gmail.com pull request https://github.com/overmesgit/django_rest_api_comparison Заключение