SlideShare a Scribd company logo
1 of 28
Содержание
1. Предисловие
2. Django Rest Framework
3. GraphQL
4. Сравнение
a. Роутинг
b. Запросы (front requests)
c. Фильтрация
d. CRUD
e. Права доступа (permissions)
f. Версионность
g. API документация
5. Результат
Предисловие
- Монолитные страницы (monolithic style)
- REST
- GraphQL
Предисловие. Монолитные страницы
- Монолитные страницы (monolithic style)
Рендеринг на стороне сервера, запросы на перерисовку отдельных частей web-
страниц посредством ajax.
Предисловие. REST
- REST
Архитектурный стиль взаимодействия компонентов распределённого приложения в
сети, пользуется популярностью с 2005 г.
Применяется для API, сайтов (SPA) и мобильных приложений.
Предисловие. GraphQL
- GraphQL
Является языком запроса данных, используется в Facebook с 2012г. Официально
презентовали в 2015г
Django Rest
Framework
Установка пакета:
pip install djangorestframework
Начальная настройка:
INSTALLED_APPS = (
...
'rest_framework',
)
REST_FRAMEWORK = { # configuration
}
urlpatterns = [
...
url(r'^api-auth/', include('rest_framework.urls'))
]
Graphene-django
Установка пакета:
pip install graphene-django
Начальная настройка:
INSTALLED_APPS = [
...
'graphene_django',
]
GRAPHENE = {
'SCHEMA': 'app.schema.schema' # Where your Graphene schema lives
}
urlpatterns = [
# ...
url(r'^graphql', GraphQLView.as_view(graphiql=True)),
]
Сравнение. Роутинг
Подключение в urls.py
urlpatterns = [
url(r'^api/v1/', include('authentication.urls')),
url(r'^api/v1/', include(users.urls')),
# url(r'^api/{version}/', include({app_name}.urls')),
]
Подключение в urls.py
urlpatterns = [
url(r'^graphql', csrf_exempt(GraphQLView.as_view(graphiql=True))),
]
Сравнение. Роутинг
Регистрация роутера
1. router.register(r'building', BuildingView,
base_name='building')
2. urlpatterns = [
3. ]
4. urlpatterns += router.urls
Подключение в urls.py
schema = Schema(query=Query, mutation=Mutations)
Сравнение. Запросы
Запрос на сущность
1. GET /api/v1/users/
2. GET /api/v1/buildings/
Оптимизация кол-ва запросов:
● Кастомные запросы для получение данных с разных
сущностей.
● Вложенные данные djangorestframework-expander
Единая точка входа
GET /graphql
1. query {
2. allUsers{ ... }
3. allBuildings{ … }
4. }
Оптимизация получения вложенных данных resolve_{method}
select_related и prefetch_related
Сравнение. Фильтрация
django-filter
1. class UserView(ListModelMixin, GenericViewSet):
2. serializer_class = UserSerializer
3. queryset = User.objects.all()
4. filter_backends =
(django_filters.rest_framework.DjangoFilterBackend,)
5. filter_fields = “__all__”
6. filter_class = UserCustomFilter
django-filter
1. class UserType(DjangoObjectType):
2. class Meta:
3. model = User
4. interfaces = (relay.Node,)
5. filter_fields = ['id', 'name']
6. class Query(ObjectType):
all_users = DjangoFilterConnectionField(UserType,
filterset_class=UserCustomFilter)
Сравнение. Фильтрация
django-filter
1. GET /api/v1/users/?category=1
2. GET /api/v1/users/?search=oleg
3. GET /api/v1/users/?search=oleg
4. GET /api/v1/users/?username__contains=oleg
django-filter
1. query{
2. allUsers(category: "QnVpbGRpbmdUeXBlOjE="){ ... }
3. allUsers(name: "oleg"){ ... }
4. allUsers(name_Icontains: "oleg"){ ... }
5. }
Сравнение. CRUD
Serializers
1. class BuildingView(RetrieveModelMixin, UpdateModelMixin,
DestroyModelMixin, ListModelMixin, CreateModelMixin,
GenericViewSet):
2. serializer_class = BuildingSerializer
Mutations
Установка пакета с доп. функциями
pip install graphene-django-extras
1. class BuildingSerializerMutation(DjangoSerializerMutation):
2. class Meta:
3. serializer_class = BuildingSerializer
Сравнение. CRUD
Serializers
1. class BuildingView(RetrieveModelMixin, UpdateModelMixin,
DestroyModelMixin, ListModelMixin, CreateModelMixin,
GenericViewSet):
2. serializer_class = BuildingSerializer
Mutations
1. class Mutations(ObjectType):
2. building_create = BuildingSerializerMutation.CreateField()
3. building_delete = BuildingSerializerMutation.DeleteField()
4. building_update = BuildingSerializerMutation.UpdateField()
Сравнение. CRUD
Serializers
Создание building
POST /api/v1/building/
1. {
2. "address": "test",
3. "name": "test",
4. }
Mutations
Создание building
1. mutation{
2. buildingCreate(newBuilding:{name: "test", address: "test
address"}){
3. building {
4. id
5. name
6. }
7. }
8. }
Сравнение. CRUD
Serializers
Изменение building
PATCH | PUT /api/v1/building/{id}/
1. {
2. "address": "string",
3. "name": "string",
4. }
Mutations
Изменение building
1. mutation{
2. buildingUpdate(newBuilding: {id: "4", name: "new name"}){
3. building{
4. id
5. name
6. }
7. ok
8. errors{
9. field
10. messages
11. }
12. }
13. }
Сравнение. CRUD
Serializers
REST запросы для CRUD оперций
1. DELETE /api/v1/building/{id}/
Mutations
Удвление building
1. mutation{
2. buildingDelete(id: "3"){
3. building {
4. id
5. name
6. }
7. }
8. }
Сравнение. Права доступа
Ограничение прав на уровне Request
1. class BuildingView(RetrieveModelMixin,
CreateModelMixin, GenericViewSet):
2. queryset = Building.objects.all()
3. permission_classes = (IsAuthenticated,
IsOwnerOrReadOnly)
Установка пакета
pip install graphene-permissions
1. class BuildingType(AuthNode, DjangoObjectType):
2. permission_classes = (AllowAuthenticated,)
3. class Meta:
4. model = Building
5. interfaces = (relay.Node,)
Сравнение. Права доступа
Кастомные права
1. class IsOwnerOrReadOnly(permissions.BasePermission):
2. """
3. Object-level permission to only allow owners of an object to
edit it.
4. """
5. def has_object_permission(self, request, view, obj):
6. if request.method in permissions.SAFE_METHODS:
7. return True
8. return obj == request.owner
1. class AuthNode:
2. permission_classes = (AllowAny, )
3. @classmethod
4. def get_node(cls, id, context, info):
5. def has_permission():
6. return all([perm() for perm in
cls.permission_classes])
7. if has_permission():
8. try:
9. object_instance =
cls._meta.model.objects.get(id=id)
10. except cls._meta.model.DoesNotExist:
11. object_instance = None
12. return object_instance
Сравнение. Права доступа
Пример запрета на все запросы
1. class DenyAny:
2. """
3. Deny for all permission
4. """
5. def has_node_permission(self, info, id):
6. return False
7. def has_mutation_permission(self, input, context, info):
8. return False
9. def has_filter_permission(self, context):
10. return False
1. class AuthNode:
2. permission_classes = (AllowAny, )
3. @classmethod
4. def get_node(cls, info, id):
5. def has_permission():
6. return all([perm().has_node_permission(info, id) for
perm in cls.permission_classes])
7. if has_permission():
8. try:
9. object_instance =
cls._meta.model.objects.get(id=id)
10. except cls._meta.model.DoesNotExist:
11. object_instance = None
12. return object_instance
13. else:
14. raise PermissionDenied(PERMISSION_DENIED_MSG)
Сравнение. Права доступа
Подключение
1. class BuildingType(AuthNode, DjangoObjectType):
2. permission_classes = (DenyAny,)
3. class Meta:
4. model = Building
5. interfaces = (relay.Node,)
6. filter_fields = ['id', 'name']
Сравнение. Версионность
Роутинг
1. GET /api/v1/users/
2. GET /api/v2/users/
3. POST /api/v1/buildings/
4. POST /api/v2/buildings/
Подключение в url.py
1. urlpatterns = [
2. url(r'^api/v1/', include('users.urls_v1')),
3. url(r'^api/v2/', include('users.urls_v2')),
4. ]
Пример с мутациями
1. class Mutations(ObjectType):
2. building_create =
BuildingSerializerMutation.CreateField(deprecation_reason
='Some one deprecation message')
Сравнение. API документация
Swagger Graphiql
Результат
DRF GraphQL
Роутинг Нужно описывать роуты один роут на все запросы
Запросы Несколько запросов, Кастомные роуты. Экспанды для
вложенных данных
Один запрос на получение нужных данных
Фильтрация django-filter django-filter
CRUD Mixins и Serializers Mutation и Serializers
Права доступа Есть удобное управление Пакет не заработал, правил классы
Версионность Добавление новых роутов Описание устаревших переменных в документации
API документация Swagger
Вся документация для работы с django
Graphiql
Нет с коробки crud операций, permissions
Версии пакетов
1. python 3.5
2. django 1.11
3. djangorestframework 3.7.1
4. django-filter 1.0.4
5. django-rest-swagger 2.1.2
6. graphene-django 2.0.0
7. graphene-django-extras 0.3.3
8. graphene-permissions 0.1.1
Ссылки
1. http://graphql.org/learn/
2. http://www.django-rest-framework.org/
3. http://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/
4. https://github.com/eamigo86/graphene-django-extras
5. https://www.techiediaries.com/django-graphql-tutorial/
6. https://www.howtographql.com/basics/0-introduction/
7. https://github.com/redzej/graphene-permissions
Конец
Всем спасибо за внимание

More Related Content

What's hot

Web осень 2013 лекция 9
Web осень 2013 лекция 9Web осень 2013 лекция 9
Web осень 2013 лекция 9Technopark
 
Java осень 2014 занятие 7
Java осень 2014 занятие 7Java осень 2014 занятие 7
Java осень 2014 занятие 7Technopark
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5Technopark
 
Л8 Django. Дополнительные темы
Л8 Django. Дополнительные темыЛ8 Django. Дополнительные темы
Л8 Django. Дополнительные темыTechnosphere1
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3Technopark
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2Technopark
 
Web осень 2013 лекция 4
Web осень 2013 лекция 4Web осень 2013 лекция 4
Web осень 2013 лекция 4Technopark
 
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективноkranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективноKrivoy Rog IT Community
 
Unit test быстрый старт
Unit test быстрый стартUnit test быстрый старт
Unit test быстрый стартAntonio
 
Эволюция BackDoor.Flashback
Эволюция BackDoor.FlashbackЭволюция BackDoor.Flashback
Эволюция BackDoor.Flashbackhexminer
 
Клиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхКлиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхKirill Zotin
 
Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социал...
Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социал...Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социал...
Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социал...zfconfua
 
Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)
Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)
Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)Dmitry Evteev
 
Лекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, LoaderЛекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, LoaderАлександр Брич
 
Лекция #6. Введение в Django web-framework
Лекция #6. Введение в Django web-frameworkЛекция #6. Введение в Django web-framework
Лекция #6. Введение в Django web-frameworkЯковенко Кирилл
 
Эффективное программирование на NodeJS
Эффективное программирование на NodeJSЭффективное программирование на NodeJS
Эффективное программирование на NodeJSYura Bogdanov
 

What's hot (18)

Web осень 2013 лекция 9
Web осень 2013 лекция 9Web осень 2013 лекция 9
Web осень 2013 лекция 9
 
Java осень 2014 занятие 7
Java осень 2014 занятие 7Java осень 2014 занятие 7
Java осень 2014 занятие 7
 
Java осень 2014 занятие 5
Java осень 2014 занятие 5Java осень 2014 занятие 5
Java осень 2014 занятие 5
 
Л8 Django. Дополнительные темы
Л8 Django. Дополнительные темыЛ8 Django. Дополнительные темы
Л8 Django. Дополнительные темы
 
Java осень 2014 занятие 3
Java осень 2014 занятие 3Java осень 2014 занятие 3
Java осень 2014 занятие 3
 
Web осень 2013 лекция 2
Web осень 2013 лекция 2Web осень 2013 лекция 2
Web осень 2013 лекция 2
 
Web осень 2013 лекция 4
Web осень 2013 лекция 4Web осень 2013 лекция 4
Web осень 2013 лекция 4
 
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективноkranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
kranonitS20 Сергей Бурма. Django - легко, быстро, эффективно
 
Unit test быстрый старт
Unit test быстрый стартUnit test быстрый старт
Unit test быстрый старт
 
Эволюция BackDoor.Flashback
Эволюция BackDoor.FlashbackЭволюция BackDoor.Flashback
Эволюция BackDoor.Flashback
 
Клиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхКлиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталях
 
Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социал...
Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социал...Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социал...
Хранение, обработка и отдача статики с использованием \Zend\File. Опыт социал...
 
Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)
Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)
Chaos Constructions HackQuest 2010 Full Disclosure (мастер-класс)
 
Лекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, LoaderЛекция Android. БД SQLite, ContentProvider, Loader
Лекция Android. БД SQLite, ContentProvider, Loader
 
Лекция #6. Введение в Django web-framework
Лекция #6. Введение в Django web-frameworkЛекция #6. Введение в Django web-framework
Лекция #6. Введение в Django web-framework
 
Bytecode
BytecodeBytecode
Bytecode
 
Эффективное программирование на NodeJS
Эффективное программирование на NodeJSЭффективное программирование на NodeJS
Эффективное программирование на NodeJS
 
Tapestry it is simple
Tapestry it is simpleTapestry it is simple
Tapestry it is simple
 

Similar to Drf vs Graphql

Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Andrey Rebrov
 
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))Noveo
 
вебинар - функциональное тестирование с использованием Selenium 2 и TestNG
вебинар - функциональное тестирование с использованием Selenium 2 и TestNGвебинар - функциональное тестирование с использованием Selenium 2 и TestNG
вебинар - функциональное тестирование с использованием Selenium 2 и TestNGAndrey Rebrov
 
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...Dev_Party
 
django cheBit'11
django cheBit'11django cheBit'11
django cheBit'11dva
 
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCDevDay
 
Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgДело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgIT61
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NETVitaly Baum
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.Igor Shkulipa
 
Метапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScriptМетапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScriptTimur Shemsedinov
 
Продвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевПродвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевYandex
 
Mobile automation uamobile
Mobile automation uamobileMobile automation uamobile
Mobile automation uamobileUA Mobile
 
iOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationiOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationAndrii Dzynia
 
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...Fedor Lavrentyev
 
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Noveo
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)Noveo
 

Similar to Drf vs Graphql (20)

Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
Бодрящий микс из Selenium и TestNG- регрессионное тестирование руками разрабо...
 
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
Библиотеки для передачи данных (Lecture 13 – multithreading, network (libs))
 
Zend Framework и Doctrine
Zend Framework и DoctrineZend Framework и Doctrine
Zend Framework и Doctrine
 
вебинар - функциональное тестирование с использованием Selenium 2 и TestNG
вебинар - функциональное тестирование с использованием Selenium 2 и TestNGвебинар - функциональное тестирование с использованием Selenium 2 и TestNG
вебинар - функциональное тестирование с использованием Selenium 2 и TestNG
 
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
Валерий Чугреев, ИСЭРТ РАН — Архитектура MVC в контексте web-разработки — про...
 
бегун
бегунбегун
бегун
 
JSSDK: Начало
JSSDK: НачалоJSSDK: Начало
JSSDK: Начало
 
django cheBit'11
django cheBit'11django cheBit'11
django cheBit'11
 
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVCАрхитектура кода нового 2ГИС Web API или куда мы дели MVC
Архитектура кода нового 2ГИС Web API или куда мы дели MVC
 
Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNgДело тестера боится: как в опытных руках могут заиграть Java и TestNg
Дело тестера боится: как в опытных руках могут заиграть Java и TestNg
 
The Old New ASP.NET
The Old New ASP.NETThe Old New ASP.NET
The Old New ASP.NET
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.
 
Метапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScriptМетапрограммирование с примерами на JavaScript
Метапрограммирование с примерами на JavaScript
 
Продвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр КошелевПродвинутое использование Celery — Александр Кошелев
Продвинутое использование Celery — Александр Кошелев
 
Mobile automation uamobile
Mobile automation uamobileMobile automation uamobile
Mobile automation uamobile
 
iOS and Android Mobile Test Automation
iOS and Android Mobile Test AutomationiOS and Android Mobile Test Automation
iOS and Android Mobile Test Automation
 
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
Industrial Programming Java - Lection Pack 01 - Building an application - Lav...
 
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
Многопоточность, работа с сетью (Lecture 12 – multithreading, network)
 
Grails & Groovy
Grails & GroovyGrails & Groovy
Grails & Groovy
 
Database (Lecture 14 – database)
Database (Lecture 14 – database)Database (Lecture 14 – database)
Database (Lecture 14 – database)
 

Drf vs Graphql

  • 1.
  • 2. Содержание 1. Предисловие 2. Django Rest Framework 3. GraphQL 4. Сравнение a. Роутинг b. Запросы (front requests) c. Фильтрация d. CRUD e. Права доступа (permissions) f. Версионность g. API документация 5. Результат
  • 4. Предисловие. Монолитные страницы - Монолитные страницы (monolithic style) Рендеринг на стороне сервера, запросы на перерисовку отдельных частей web- страниц посредством ajax.
  • 5. Предисловие. REST - REST Архитектурный стиль взаимодействия компонентов распределённого приложения в сети, пользуется популярностью с 2005 г. Применяется для API, сайтов (SPA) и мобильных приложений.
  • 6. Предисловие. GraphQL - GraphQL Является языком запроса данных, используется в Facebook с 2012г. Официально презентовали в 2015г
  • 7. Django Rest Framework Установка пакета: pip install djangorestframework Начальная настройка: INSTALLED_APPS = ( ... 'rest_framework', ) REST_FRAMEWORK = { # configuration } urlpatterns = [ ... url(r'^api-auth/', include('rest_framework.urls')) ]
  • 8. Graphene-django Установка пакета: pip install graphene-django Начальная настройка: INSTALLED_APPS = [ ... 'graphene_django', ] GRAPHENE = { 'SCHEMA': 'app.schema.schema' # Where your Graphene schema lives } urlpatterns = [ # ... url(r'^graphql', GraphQLView.as_view(graphiql=True)), ]
  • 9. Сравнение. Роутинг Подключение в urls.py urlpatterns = [ url(r'^api/v1/', include('authentication.urls')), url(r'^api/v1/', include(users.urls')), # url(r'^api/{version}/', include({app_name}.urls')), ] Подключение в urls.py urlpatterns = [ url(r'^graphql', csrf_exempt(GraphQLView.as_view(graphiql=True))), ]
  • 10. Сравнение. Роутинг Регистрация роутера 1. router.register(r'building', BuildingView, base_name='building') 2. urlpatterns = [ 3. ] 4. urlpatterns += router.urls Подключение в urls.py schema = Schema(query=Query, mutation=Mutations)
  • 11. Сравнение. Запросы Запрос на сущность 1. GET /api/v1/users/ 2. GET /api/v1/buildings/ Оптимизация кол-ва запросов: ● Кастомные запросы для получение данных с разных сущностей. ● Вложенные данные djangorestframework-expander Единая точка входа GET /graphql 1. query { 2. allUsers{ ... } 3. allBuildings{ … } 4. } Оптимизация получения вложенных данных resolve_{method} select_related и prefetch_related
  • 12. Сравнение. Фильтрация django-filter 1. class UserView(ListModelMixin, GenericViewSet): 2. serializer_class = UserSerializer 3. queryset = User.objects.all() 4. filter_backends = (django_filters.rest_framework.DjangoFilterBackend,) 5. filter_fields = “__all__” 6. filter_class = UserCustomFilter django-filter 1. class UserType(DjangoObjectType): 2. class Meta: 3. model = User 4. interfaces = (relay.Node,) 5. filter_fields = ['id', 'name'] 6. class Query(ObjectType): all_users = DjangoFilterConnectionField(UserType, filterset_class=UserCustomFilter)
  • 13. Сравнение. Фильтрация django-filter 1. GET /api/v1/users/?category=1 2. GET /api/v1/users/?search=oleg 3. GET /api/v1/users/?search=oleg 4. GET /api/v1/users/?username__contains=oleg django-filter 1. query{ 2. allUsers(category: "QnVpbGRpbmdUeXBlOjE="){ ... } 3. allUsers(name: "oleg"){ ... } 4. allUsers(name_Icontains: "oleg"){ ... } 5. }
  • 14. Сравнение. CRUD Serializers 1. class BuildingView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, ListModelMixin, CreateModelMixin, GenericViewSet): 2. serializer_class = BuildingSerializer Mutations Установка пакета с доп. функциями pip install graphene-django-extras 1. class BuildingSerializerMutation(DjangoSerializerMutation): 2. class Meta: 3. serializer_class = BuildingSerializer
  • 15. Сравнение. CRUD Serializers 1. class BuildingView(RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, ListModelMixin, CreateModelMixin, GenericViewSet): 2. serializer_class = BuildingSerializer Mutations 1. class Mutations(ObjectType): 2. building_create = BuildingSerializerMutation.CreateField() 3. building_delete = BuildingSerializerMutation.DeleteField() 4. building_update = BuildingSerializerMutation.UpdateField()
  • 16. Сравнение. CRUD Serializers Создание building POST /api/v1/building/ 1. { 2. "address": "test", 3. "name": "test", 4. } Mutations Создание building 1. mutation{ 2. buildingCreate(newBuilding:{name: "test", address: "test address"}){ 3. building { 4. id 5. name 6. } 7. } 8. }
  • 17. Сравнение. CRUD Serializers Изменение building PATCH | PUT /api/v1/building/{id}/ 1. { 2. "address": "string", 3. "name": "string", 4. } Mutations Изменение building 1. mutation{ 2. buildingUpdate(newBuilding: {id: "4", name: "new name"}){ 3. building{ 4. id 5. name 6. } 7. ok 8. errors{ 9. field 10. messages 11. } 12. } 13. }
  • 18. Сравнение. CRUD Serializers REST запросы для CRUD оперций 1. DELETE /api/v1/building/{id}/ Mutations Удвление building 1. mutation{ 2. buildingDelete(id: "3"){ 3. building { 4. id 5. name 6. } 7. } 8. }
  • 19. Сравнение. Права доступа Ограничение прав на уровне Request 1. class BuildingView(RetrieveModelMixin, CreateModelMixin, GenericViewSet): 2. queryset = Building.objects.all() 3. permission_classes = (IsAuthenticated, IsOwnerOrReadOnly) Установка пакета pip install graphene-permissions 1. class BuildingType(AuthNode, DjangoObjectType): 2. permission_classes = (AllowAuthenticated,) 3. class Meta: 4. model = Building 5. interfaces = (relay.Node,)
  • 20. Сравнение. Права доступа Кастомные права 1. class IsOwnerOrReadOnly(permissions.BasePermission): 2. """ 3. Object-level permission to only allow owners of an object to edit it. 4. """ 5. def has_object_permission(self, request, view, obj): 6. if request.method in permissions.SAFE_METHODS: 7. return True 8. return obj == request.owner 1. class AuthNode: 2. permission_classes = (AllowAny, ) 3. @classmethod 4. def get_node(cls, id, context, info): 5. def has_permission(): 6. return all([perm() for perm in cls.permission_classes]) 7. if has_permission(): 8. try: 9. object_instance = cls._meta.model.objects.get(id=id) 10. except cls._meta.model.DoesNotExist: 11. object_instance = None 12. return object_instance
  • 21. Сравнение. Права доступа Пример запрета на все запросы 1. class DenyAny: 2. """ 3. Deny for all permission 4. """ 5. def has_node_permission(self, info, id): 6. return False 7. def has_mutation_permission(self, input, context, info): 8. return False 9. def has_filter_permission(self, context): 10. return False 1. class AuthNode: 2. permission_classes = (AllowAny, ) 3. @classmethod 4. def get_node(cls, info, id): 5. def has_permission(): 6. return all([perm().has_node_permission(info, id) for perm in cls.permission_classes]) 7. if has_permission(): 8. try: 9. object_instance = cls._meta.model.objects.get(id=id) 10. except cls._meta.model.DoesNotExist: 11. object_instance = None 12. return object_instance 13. else: 14. raise PermissionDenied(PERMISSION_DENIED_MSG)
  • 22. Сравнение. Права доступа Подключение 1. class BuildingType(AuthNode, DjangoObjectType): 2. permission_classes = (DenyAny,) 3. class Meta: 4. model = Building 5. interfaces = (relay.Node,) 6. filter_fields = ['id', 'name']
  • 23. Сравнение. Версионность Роутинг 1. GET /api/v1/users/ 2. GET /api/v2/users/ 3. POST /api/v1/buildings/ 4. POST /api/v2/buildings/ Подключение в url.py 1. urlpatterns = [ 2. url(r'^api/v1/', include('users.urls_v1')), 3. url(r'^api/v2/', include('users.urls_v2')), 4. ] Пример с мутациями 1. class Mutations(ObjectType): 2. building_create = BuildingSerializerMutation.CreateField(deprecation_reason ='Some one deprecation message')
  • 25. Результат DRF GraphQL Роутинг Нужно описывать роуты один роут на все запросы Запросы Несколько запросов, Кастомные роуты. Экспанды для вложенных данных Один запрос на получение нужных данных Фильтрация django-filter django-filter CRUD Mixins и Serializers Mutation и Serializers Права доступа Есть удобное управление Пакет не заработал, правил классы Версионность Добавление новых роутов Описание устаревших переменных в документации API документация Swagger Вся документация для работы с django Graphiql Нет с коробки crud операций, permissions
  • 26. Версии пакетов 1. python 3.5 2. django 1.11 3. djangorestframework 3.7.1 4. django-filter 1.0.4 5. django-rest-swagger 2.1.2 6. graphene-django 2.0.0 7. graphene-django-extras 0.3.3 8. graphene-permissions 0.1.1
  • 27. Ссылки 1. http://graphql.org/learn/ 2. http://www.django-rest-framework.org/ 3. http://docs.graphene-python.org/projects/django/en/latest/tutorial-plain/ 4. https://github.com/eamigo86/graphene-django-extras 5. https://www.techiediaries.com/django-graphql-tutorial/ 6. https://www.howtographql.com/basics/0-introduction/ 7. https://github.com/redzej/graphene-permissions