Разделяем формирование списка доступных ресурсов и разграничение доступа

Считаю необходимым разделять следующие задачи

  1. Формирование списка ресурсов доступных субъекту

  2. Разграничение доступа к операциям с ресурсами

Пример требований

Врачу необходимо отображать пациентов из региона с которым связан врач.

Частый подход к реализации

  1. API с эндпоинтом /api/patients/, который возвращает только тех пациентов, которых должен видеть текущий пользователь. Т.е. API занимается как формированием списка ресурсов доступных субъекту, так и авторизацией. Фактически политика доступа описывается SQL-запросом или ORM.

  2. Фронтенд делает запрос к /api/patients/ и занимается только отображением

Предлагаемый подход

  1. Эндпоинт /api/patients/ возвращает всех пациентов, но поддерживает фильтрацию по атрибутам, т.е. можно сделать запрос /api/patients/?region-id=1 и получить пациентов только из региона 1

  2. Access gateway: умеет идентифицировать пользователя, хранит в себе политики доступа и проверяет каждый запрос на соответствие политикам доступа, т.е. авторизует каждый запрос к ресурсу.

  3. Фронтенд делает запрос к /api/patients/?region-id=x, где x — регион текущего пользователя. Тем самым формирует список ресурсов доступных субъекту.

Что это даёт

  1. Изменение логики отображения не требует вмешательства бекенд-разработчиков если логика укладывается в существующие политики доступа.

  2. Разработка, изменение политик доступа не требует вмешательства в бизнес-логику, что уменьшает вероятность допустить ошибку в бизнес-функциях.

  3. Аудит политик доступа не требует погружения в код бизнес-логики, что уменьшает время, сложность, стоимость и качество аудита.

  4. Этап разработки политик доступа переносим в конец, что позволит реализовать функциональные требования и протестировать результат быстрее.

Глоссарий

Ресурс

некий информационный актив, к примеру статья, карточка пациента, файл

Субъект

человек, информационная система отправляющая к нам запрос

P.S. не готов дискутировать на тему использования GraphQL, но вам мысленно примерить описанный подход на GraphQL советую.