Как стать автором
Обновить

Комментарии 11

Рассмтаривал такой вариант, как один из подходов (см. №1 Написать разные TaskViewSet для Исполнителя и Заказчика), но он не показался мне лучшим.

Нашел у этого подхода три минуса, один из которых: Employee и Сompany это все-таки не путь к ресурсу, а роль, с которой я работаю в этом ресурсе. А насколько мы знаем в url при REST подходе мы должны использовать исключительно ресурсы, но не роли (не исключаю, что тут я уже сам себя передумал)

Лично мне не нравится решение на if/elsif/else — я бы сделал либо наследование либо что-то более общее.


У вас все эндпоинты одинаковые для всех профилей? Если да — то переключатель в query выглядит не таким злом.


Если же нет — то вы сами все усложняете, по крайней мере в Swagger. Сложно будет понять что к чему относится. Имея mode в url вы сразу разделяете области. И проверять mode тоже можно в одном месте (dispatch()?) вместе с правами.


А вам хватает автогенерации swaggerdoc? Я в свое время намучился настраивать ее и решил писать схему руками в формате OpenAPI.

Если же нет — то вы сами все усложняете, по крайней мере в Swagger. Сложно будет понять что к чему относится.

Хорошо подмечено, ресурс в моейм примере имеет как общие для всех профилей эндпоинты, так и различные. И вопрос наверное каких больше.

Если больше общих, то имеет смысл оставлять это в одном блоке с одной вью, и переключением query.
Если же большинство эндпоинтов различны для каждого профиля, то вариант с разделение на два вью (на блоки /{mode}/task) становится привлекательнее, так как дублирования урлов в спеке и дублирования кода почти не будет.

А вам хватает автогенерации swaggerdoc? Я в свое время намучился настраивать ее и решил писать схему руками в формате OpenAPI.

drf_yasg генерит вполне приличную спеку.

Мы используем swagger для удобства локальной разработки и для предоставления спецификации на фронт разработку.

Наружу она не торчит, поэтому какие-то недостатки (вроде небольших косяков с описанием ресурсов с вложенными сериалайзерами) мы ему прощаем, так как он дает полную автоматизацию этого процесса.

Единственный раз когда уперлись в возможности drf_yasg, когда пытались использовать его для генерации запросов к апи запущенному на https (на стейджинге), промучались с кастомизацией дефолтной схемы, но так и не добились успеха.
А насколько мы знаем в url при REST подходе мы должны использовать исключительно ресурсы, но не роли (не исключаю, что тут я уже сам себя передумал)

Ни REST, ни спецификации URI и HTTP не ограничивают сферу того, что может быть отнесено к "ресурсам". Ресурс — всего лишь цель гиперссылки, любой адресуемый концепт вписывается в это понятие. Даже сервис или действие могут быть адресованы URI.


https://tools.ietf.org/html/rfc3986#section-1.1
https://tools.ietf.org/html/rfc7231#section-2
https://www.ics.uci.edu/~fielding/pubs/dissertation/evaluation.htm#sec_6_2_1

Спасибо, Вы говорите все верно. Как говорится «учите матчасть»

REST не накладывает никаких требований на ресурс. Тогда этот аргумент полностью снимается.

Но другие минусы у этого подхода остаются:
1. Несколько вьюх вместо одной (труднее поддерживать)
2. Спецификация расширяется от общих урлов для обоих профилей

Попробую сразу же и оспорить эти минусы:
1. В целом решается через наследование, но придется постоянно постоянно делать лишний слой для каждого следующего «общего» ресурса. Дело привычки, кому как удобнее организовывать код.

2. С одной стороны мы делаем больше эндпоинтов (но кто сказал, что это проблема), ведь главное чтобы было понятно как с этими урлами работать.

Одно могу сказать точно, решение имеет место быть, и выглядит неплохо!

Окончательное решение наверное должно идти от того, как апи будет использовать клиент (в данном случае фронт/мобильные приложения).
НЛО прилетело и опубликовало эту надпись здесь
Рекомендую воспользоваться проектом rules, который позволяет очень удобно и гибко реализовывать правила авторизации.

Спасибо за ссылку, изучу!

Это не так. Пермишны в DRF можно комбинировать любым образом:

Верно, я об этом написал, возможность комбинировать пермишны появилась в drf с версии 3.9 (https://www.django-rest-framework.org/community/3.9-announcement/#composable-permission-classes)

Вы "сложили все яйца в одну корзину" и потом пытаетесь подпорками и if-чиками бить по рукам клиента, который потянулся не за своим яйцом.
Разделите "яйца" по отдельным "корзинам" и станет немного проще. Сделайте, например, /company_tasks и /emploee_tasks. Так и документация станет понятнее.
Я бы предложил вообще сделать вот так:
/<user_id>/company_tasks
/<user_id>/emploee_tasks
что бы еще точнее конкретизировать содержимое "корзин". Но я не в курсе насколько легко такое делать в DRF.
С роутингом по регекспам очень неудобно делать вложенные ресурсы т.к. не получается разнести в коде по разным ресурсам ответственность за доступ к его подресурсам. Приходится всю логику с проверками делать во вьюшке ресурса на который указывает url. Это в свою очередь мешает переиспользованию кода, т.к. в другом месте эту вьюшку не получится прикрутить из-за того, что там будут другие проверки и условия для извлечения того же самого ресурса (например надо получить задачу заказчика от лица исполнителя).
Для REST очень хорошо подходит механизм роутинга, который называется traversal. Но его нет в джанге и в DRF видимо тоже.

А зачем user_id в URL?

Что бы админом зайти к нему в ресурсы и всё там сломать (шутка).
Или не админом, а просто другим пользователем, у которого есть разрешение на доступ (например член семьи). В общем тут та же история про "яйца в корзине". Одна "корзина" в api удобна для админского UI, а для пользовательского надо чётко, на уровне url, разделять ресурсы. Так проще реализовать доступ к "чужим" ресурсам — не надо лепить костыли для указания серверу, что Я не Я, а типа другой пользователь, который дал мне доступ.
И в логах понятнее становится к ресурсам какого юзера был запрос и какой (возможно другой) юзер сделал этот запрос.
Тут подходит аналогия с раскладкой папок в многопользовательских ОС — у каждого пользователя есть своя папка, а не все в одной ютятся.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории