Почему в соглашении говорится, что имена таблиц БД должны быть единичными, а ресурсы RESTful - множественными?

27

Это довольно устоявшееся соглашение, что имена таблиц базы данных, по крайней мере в SQL, должны быть единичными. SELECT * FROM user;Смотрите этот вопрос и обсуждение .

Это также довольно устоявшееся соглашение о том, что имена ресурсов API RESTful должны быть множественными. GET /users/123и POST /usersувидеть это .

В простейшем API, поддерживаемом базой данных, именем ресурса в URL будет таблица, а элементы данных в телах URL и запросов / ответов будут отображаться непосредственно в столбцы в БД. Концептуально я не вижу разницы между работой с данными с помощью этого теоретического API и работой с ними напрямую с помощью SQL. И из-за этого, разница в именных соглашениях между userи usersне имеет смысла для меня.

Как можно оправдать разницу в плюрализации, когда концептуально API REST и SQL делают одно и то же?

smitelli
источник
3
Нет единого соглашения в именовании таблиц БД или именования ресурсов RESTful, которому следуют все. Наоборот, может быть много соглашений. Не удивительно, что некоторые могут столкнуться.
Эрик Кинг,
13
Нет такой установленной конвенции. Я всегда использовал имена таблиц во множественном числе. пользователи , учетные записи и т. д., поскольку они держат более одной вещи.
GrandmasterB
2
@GrandmasterB Соглашение существует, и оно берет свое начало в реляционной модели Кодда, где «отношения» (которые становятся таблицами, а не связываются с отношениями) имеют единичные имена, потому что отношение - это список вещей, а не несколько списков вещей. Каждое отношение - это один список. Модель отношений предметных сущностей. Имена сущностей являются единственными в реляционной модели Кодда. Есть много литературы об этом, чтобы сказать, что это не существует. Но вы можете использовать множественные имена, если хотите.
Тулаинс Кордова
4
@ user61852 Есть люди, которые могут использовать его по соглашению. Но это ни в коем случае не является общепринятой отраслевой конвенцией, представленной в этом вопросе, как, скажем, CamelCase или MarkDown.
GrandmasterB
4
Также имейте в виду, что REST не является протоколом доступа к базе данных. Нет никаких причин, по которым соглашения об именах БД (с какими бы вы ни шли) и соглашения об именах URL (с какими бы вы ни шли) должны быть одинаковыми, они не имеют ничего общего друг с другом. Два очень разных домена. Нет больше смысла размышлять о том, почему базы данных используют единственное число, а URL-адреса используют множественное число, чем размышлять о том, почему базы данных используют единственное число, но мой системный администратор называет его каталоги файловой системы множественным числом. Плохо разработанные веб-фреймворки заставляют людей думать, что REST как-то связан с доступом к БД, но это не так.
Кормак Малхолл,

Ответы:

12

Спецификация REST (с каким бы уровнем вы не хотели идти) не была предназначена для доступа к базе данных. Он пытается привнести стандартизацию в доступ к API. Упомянутые соглашения SQL (хотите ли вы их использовать или нет) не были разработаны с учетом доступа к API. Они для написания запросов SQL.

Таким образом, проблема, которую нужно распаковать, заключается в концептуальном понимании того, что API-интерфейс отображается непосредственно в базу данных. Мы можем найти это как анти-паттерн, по крайней мере, еще в 2009 году .

Основная причина, это плохо? Код, описывающий "как эта операция влияет на мои данные?" становится клиентским кодом .

Это имеет довольно ужасные последствия для API. (не исчерпывающий список)

Это затрудняет интеграцию с API

Я представляю шаги для создания нового пользователя, задокументированного примерно так:

  1. POST /users { .. }
  2. POST /usersettings { .. } с некоторыми значениями по умолчанию
  3. POST /confirmemails { .. }

Но как вы справляетесь с провалом шага № 2? Сколько раз эта же логика обработки копируется в другие клиенты вашего API?

Эти операции с данными часто проще упорядочить на стороне сервера, при этом они инициируются клиентом как одна операция. Например POST /newusersetup. Администраторы БД могут распознать это как хранимую процедуру, но операция API может иметь последствия не только для базы данных.

Защита API становится черной дырой отчаяния

Допустим, вам нужно объединить две учетные записи пользователей.

  1. GET /users/1
  2. PUT /users/2 { .. }
  3. DELETE /users/1

Как вы собираетесь настроить разрешение пользователя, чтобы разрешить функцию слияния, не разрешая удаление пользователя? Является ли удаление пользователя даже справедливо представленным, DELETE /users/1когда /usersettingsтакже существует?

Операции API следует рассматривать как операции более высокого уровня (чем база данных), которые могут вызвать многочисленные изменения в системе.

Обслуживание становится сложнее

... потому что ваши клиенты зависят от вашей структуры базы данных.

Основываясь на моем опыте с этим сценарием:

  • Вы не можете переименовать или удалить существующие таблицы / столбцы. Даже когда они названы неправильно для их функции или больше не используются. Клиенты сломаются.
  • Новые функции не могут изменить существующие структуры данных, поэтому их данные и функциональные возможности часто искусственно разделяются, даже если они целостно связаны с существующей функцией.
  • Кодовая база постепенно становится все труднее понять из-за фрагментации, запутанных имен и остатков багажа, которые невозможно безопасно удалить.
  • Все, кроме тривиальных изменений, становятся все более рискованными и трудоемкими.
  • Система застаивается и в итоге заменяется.

Не раскрывайте свою структуру базы данных непосредственно клиентам ... особенно клиентам, над которыми у вас нет контроля над развитием. Используйте API, чтобы сузить клиента до только допустимых операций.

Так что, если вы используете API-интерфейс как интерфейс непосредственно в базе данных, плюрализация - это наименьшее количество ваших забот. Для других экспериментов я бы предложил потратить некоторое время на определение операций более высокого уровня, которые должен представлять API. И если взглянуть на это с такой точки зрения, то между множественными именами объектов API и именами отдельных объектов SQL нет конфликта. Они там по разным причинам.

Кейси Спикман
источник
1
Отвечает на другой вопрос. OP не подразумевает прямую ассоциацию сущностей API и БД, а только присутствие некоторых сущностей в обоих контекстах.
Базилевс
2
Не стесняйтесь оставлять ответ на вопрос, который, по вашему мнению, задают.
Кейси Спикман
4
@Basilevs На самом деле я думаю, что это действительно отвечает на вопрос. Иногда ответы могут показаться косвенными, когда вопрос основан на неправильных предположениях. «Присутствие некоторых субъектов в обеих контекстах» означает , что они один и то же лицо, что означает 1 к 1 соответствие между некоторыми и не другими. Такое соответствие API над сложной моделью данных подразумевает некорректный дизайн.
Алуан Хаддад
Среди этих причин я перестал использовать Spring Data Rest.
Себастьян ван ден Брук
4

REST API и SQL НЕ «делают одно и то же»

ОП спрашивает:

Как можно оправдать разницу в плюрализации, когда концептуально API REST и SQL делают одно и то же?

Ах, но кузнечик, может показаться, что интерфейс RESTful и таблицы SQL «делают одно и то же», но хорошая гигиена программирования говорит нам, что всегда существует промежуточный уровень, который является посредником между REST API и базой данных. Игнорировать этот момент - значит отклониться от пути к просветлению программного обеспечения! :)

Таким образом, API-интерфейсы RESTful и таблицы SQL могут успешно следовать собственным соглашениям об именовании, которые хорошо документированы и подробно обсуждаются в других местах.

fearless_fool
источник