Перенос логики работы с БД из серверной части в клиентскую

Возник неоднозначный вопрос касательно клиент-серверной архитектуры:

Вводные:

  1. Пишет все 1 разработчик (backend и frontend).
  2. Единица измерения эффективности - время разработки (например, изменить код в клиенте быстрее, чем изменить его на клиенте и сервере).

В большинстве сайтов\приложений, которые я пишу, прослеживается следующая логика:

  • Клиент - несет в себе логику отображения данных. Например, при нажатии кнопки - клиент запрашивает у сервера список объектов (передавая в параметрах запроса параметры выборки) и затем отображает клиенту.
  • Сервер - несет логику "прослойки" между БД и клиентом, предоставляя роуты доступа (с методами для работы с GET, POST и т.д). Например, сервер получает запрос GET https://domain.com/users с параметрами выборки (offset, columns), парсит эти параметры в SQL запрос, достает из БД список пользователей и возвращает обратно клиенту.
  • Сервер - хранит данные. Здесь понятно.

В какой-то момент я пришел к выводу, что клиент и сервер дублируют логику друг друга. Условно говоря, клиент имеет функционал для доступа к URL'y /users/ (с методам getUsers(), removeUser(id) и т.д.), а сервер предоставляет роуты (с методам get(users), delete(user) и т.д.) для работы с таблицей users.


Ради интереса, я изменил логику сервера, чтобы был только один роут доступа к данным: https://domain.com/database.

В качестве параметров, этот роут принимает:

  1. Название таблиц(-ы) (в нашем случае users, но можно сделать и join).
  2. Параметры для выборки данных (метод select\delete\etc., параметры where, offset, sort и т.д. в виде JSON-объекта).
  3. Данные пользователя. При запросе через этот роут, сервер проверяет, авторизован ли пользователь и имеет ли он доступ к таблицам (например, пользователь с правами user может получить только доступ к базе users, но не к staff и т.д.).

При каждом запросе проверяется авторизация и проверка параметров на SQL-инъекцию (чтобы не прошел параметр method: "SELECT * FROM users; -- ").

В результате, если раньше сервер имел логику настройки роутов и проверки данных - отпала логика настройки роутов и дублирования методов GET, POST и т.д. для каждой таблицы. Теперь есть только 3 универсальных метода GET POST DELETE для всей базы данных.


Однако, видимо, есть причины, почему такая практика не получила распространения. Первая мысль - возможны проблемы с защитой. Но авторизация и проверка данных на SQL инъекции осталась. Грубо говоря, разницы между двумя вариантами в плане защиты нет.

Вопрос: почему так не делают? Какие минусы у такого подхода, что может пойти не так и следует ли дальше использовать такой подход?

Возможный ответ: почему нельзя! Можно! Есть же Google Firebase!

Уточнение: вопрос довольно объемный и однозначного ответа нет. Поэтому готов обсуждать любые утверждения в ответах\комментариях, чтобы "дойти" до истины.


Ответы (2 шт):

Автор решения: Morewind
  1. Раскрывается структура БД для конечного пользователя.
  2. Жесткая привязка всей программы к конкретной структуре БД. Нельзя переименовать поле таблицы, разделить или объединить таблицы, вынести какие-либо данные в другие БД (например, с целями кеширования) без поиска и изменения всех мест где есть использование затронутых структур.
  3. Подозреваю, что избыточное дублирование кода в разных частях такой программы и усложнение чтения кода. Вместо GET /user/{id} надо писать полноценный SQL запрос да еще в нестандартном виде.
  4. Привязка к одной СУБД, нельзя написать еще одну "прослойку" для другой базы, которая внешне реализует те же методы что и первая, но внутри использует совсем другую БД. Как был у неё get(users) так и остался, но внутри совсем другая обработка.
→ Ссылка
Автор решения: Denisio
  1. Тебе понадобится сервер с row level security. Потому что если без - все проверки и ограничения на клиенте будут бесполезны. Клиент заведомо неподконтролен, любой мамкин хакер возьмет curl и отправит запрос на твой сервер для получения не предназначенных ему данных.

  2. В случае наличия полноценного backend ты можешь регулировать всё что захочешь - кэширование, балансировка, аутентификация разными методами и другие ручки, которые не будут доступны тебе, если клиент будет напрямую лазить в БД. Потому что см. п.1 - обязательно и очень быстро найдутся желающие потрогать СУБД поплотнее в части не принадлежащих им данных. По сути бакенд это изоляция клиента от конкретной реализации механизмов обработки и хранения. Имея бакенд ты можешь делать клиентов на разных языках и платформах, которые смогут использовать одно и то же API. И все обновления бакенда никак не повлияют на клиентов, потому что у них есть API.

  3. Представляется некоторые сложности с логированием в случае прямого доступа к СУБД. Кто какие запросы отправил, где, кто и когда что поменял.

→ Ссылка