web-dev-qa-db-fra.com

Pourquoi la convention dit-elle que les noms de table DB doivent être singuliers mais les ressources RESTful plurielles?

C'est une convention assez établie que les noms de table de base de données, en SQL au moins, doivent être singuliers. SELECT * FROM user; Voir cette question et discussion .

C'est également une convention assez établie que les noms de ressources de l'API RESTful doivent être pluriels. GET /users/123 et POST /users Voir celui-ci .

Dans l'API la plus simple basée sur une base de données, le nom de la ressource dans l'URL serait la table, et les éléments de données dans l'URL et les corps de demande/réponse seraient mappés directement aux colonnes de la base de données. Sur le plan conceptuel, je ne vois pas de différence entre opérer sur les données via cette API théorique et opérer directement via SQL. Et à cause de cela, la différence de conventions de dénomination entre user et users n'a pas de sens pour moi.

Comment justifier la différence de pluralisation lorsque, conceptuellement, l'API REST et SQL font la même chose?

30
smitelli

La spécification REST (quel que soit le niveau que vous souhaitez utiliser) n'a pas été conçue comme un accès à la base de données. Elle tente de normaliser l'accès à l'API. Les conventions SQL mentionnées (si vous souhaitez les utiliser ou non) ou non) n'ont pas été conçus en pensant à l'accès API. Ils sont destinés à l'écriture de requêtes SQL.

Donc, le problème à décompresser ici est la compréhension conceptuelle qu'une API mappe directement à la base de données. Nous pouvons trouver cela décrit comme un anti-modèle au moins jusqu'en 2009 .

La principale raison pour laquelle c'est mauvais? Le code décrivant "comment cette opération affecte-t-elle mes données?" devient le code client .

Cela a des effets assez terribles sur l'API. (liste non exhaustive)

Cela rend l'intégration avec l'API difficile

J'imagine les étapes pour créer un nouvel utilisateur documenté comme ceci:

  1. POST /users { .. }
  2. POST /usersettings { .. } avec quelques valeurs par défaut
  3. POST /confirmemails { .. }

Mais comment gérez-vous un échec de l'étape 2? Combien de fois cette même logique de manipulation est-elle copiée-collée à d'autres clients de votre API?

Ces opérations de données sont souvent plus faciles à séquencer côté serveur, tout en étant initiées à partir du client en une seule opération. Par exemple. POST /newusersetup. Les administrateurs de base de données peuvent reconnaître cela comme une procédure stockée, mais le fonctionnement de l'API peut avoir des effets au-delà de la base de données.

Sécuriser l'API devient un trou noir de désespoir

Disons que vous devez fusionner deux comptes d'utilisateurs.

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

Comment allez-vous configurer une autorisation utilisateur pour autoriser la fonction de fusion sans autoriser la suppression de l'utilisateur? Supprime un utilisateur même équitablement représenté par DELETE /users/1 quand /usersettings existe aussi?

Les opérations d'API doivent être considérées comme des opérations de niveau supérieur (à celui de la base de données) qui peuvent entraîner plusieurs modifications dans le système.

L'entretien devient plus difficile

... car vos clients dépendent de la structure de votre base de données.

Sur la base de mon expérience avec ce scénario:

  • Vous ne pouvez pas renommer ou supprimer des tables/colonnes existantes. Même lorsqu'ils ne sont pas nommés correctement pour leur fonction ou ne sont plus utilisés. Les clients vont se casser.
  • Les nouvelles fonctionnalités ne peuvent pas modifier les structures de données existantes, de sorte que ses données et fonctionnalités sont souvent artificiellement séparées, même lorsqu'elles appartiennent globalement à une fonctionnalité existante.
  • La base de code devient progressivement plus difficile à comprendre en raison de la fragmentation, des noms confus et des bagages restants qui ne peuvent pas être retirés en toute sécurité.
  • Tous les changements, sauf insignifiants, deviennent de plus en plus risqués et prennent du temps.
  • Le système stagne et est finalement remplacé.

N'exposez pas votre structure de base de données directement aux clients ... en particulier les clients sur lesquels vous n'avez pas de contrôle de développement. Utilisez une API pour limiter le client à des opérations uniquement valides.

Donc, si vous utilisez une API comme une simple interface directement dans une base de données, la pluralisation est le moindre de vos soucis. Pour autre chose qu'une expérience jetable, je suggérerais de passer un peu de temps à déterminer les opérations de niveau supérieur que l'API devrait représenter. Et lorsque vous regardez les choses de cette façon, il n'y a pas de conflit entre les noms d'entités API pluralisés et les noms d'entités SQL singuliers. Ils sont là pour différentes raisons.

13
Kasey Speakman

L'API REST et le SQL NE "font PAS la même chose"

Le PO demande:

Comment justifier la différence de pluralisation lorsque, conceptuellement, l'API REST et SQL font la même chose?

Ah, mais Grasshopper, il peut apparaître que l'interface RESTful et les tables SQL "font la même chose", mais une bonne hygiène de programmation nous dit qu'il y a toujours une couche intermédiaire qui sert d'intermédiaire entre le REST API et base de données. Ignorer ce point, c'est s'éloigner du chemin vers l'illumination logicielle! :)

Les API RESTful et les tables SQL peuvent donc suivre leurs propres conventions de dénomination idiomatiques, qui sont bien documentées et discutées en détail ailleurs.

5
fearless_fool