web-dev-qa-db-fra.com

REST vs JSON-RPC?

J'essaie de choisir entre REST et JSON-RPC pour développer une API pour une application Web. Lequel est le plus facile à utiliser pour les clients API?

Mise à jour 2015: J'ai trouvé REST plus facile à développer et à utiliser pour une API servie sur Web/HTTP, car le protocole HTTP existant et mature, compris par le client et le serveur, peut être exploité par l'API. . Par exemple, l'API peut utiliser les codes de réponse, les en-têtes, les requêtes, les corps de publication, la mise en cache et bien d'autres fonctionnalités sans effort ni configuration supplémentaire.

239
Ali Shakiba

Le problème fondamental avec RPC est le couplage. Les clients RPC sont étroitement liés à la mise en œuvre des services de plusieurs manières et il devient très difficile de les modifier sans casser les clients:

  • Les clients sont tenus de connaître les noms de procédure;
  • Les paramètres de procédure ordre, types et nombre comptent. Il n'est pas si facile de changer les signatures de procédures (nombre d'arguments, ordre des arguments, types d'arguments, etc.) côté serveur sans interrompre les implémentations client.
  • Le style RPC n'expose que les extrémités de la procédure + les arguments de la procédure. Il est impossible pour le client de déterminer ce qui peut être fait ensuite.

Par contre, dans le style REST, il est très facile de guider les clients en incluant les informations de contrôle dans les représentations (en-têtes HTTP + représentation). Par exemple:

  • Il est possible (et même obligatoire) d'intégrer des liens annotés avec des types de relation de lien qui transmettent le sens de ces adresses URI;
  • Les implémentations client ne doivent pas nécessairement dépendre de noms de procédure et d'arguments particuliers. Au lieu de cela, les clients dépendent des formats de message. Cela crée la possibilité d'utiliser des bibliothèques déjà implémentées pour des formats de média particuliers (par exemple, Atom, HTML, Collection + JSON, HAL, etc.).
  • Il est possible de changer facilement d'URI sans casser les clients dans la mesure où ils ne dépendent que de relations de lien enregistrées (ou spécifiques à un domaine);
  • Il est possible d'incorporer des structures de type formulaire dans des représentations, donnant ainsi aux clients la possibilité d'exposer ces descriptions en tant que capacités d'interface utilisateur si l'utilisateur final est humain.
  • La prise en charge de la mise en cache est un avantage supplémentaire.
  • Codes d'état normalisés;

Il y a beaucoup plus de différences et d'avantages du côté REST.

208
ioseb

J'ai exploré la question en détail et décidé que la pure REST est beaucoup trop restrictive et que le RPC est ce qu'il y a de mieux, même si la plupart de mes applications sont des applications CRUD. Si vous vous en tenez à REST, vous finirez par vous casser la tête en vous demandant comment ajouter facilement une autre méthode nécessaire à votre API à des fins spécifiques. Dans de nombreux cas, le seul moyen de le faire avec REST consiste à créer un autre contrôleur, ce qui peut compliquer indûment votre programme.

Si vous choisissez RPC, la seule différence est que vous spécifiez explicitement le verbe en tant que partie de l'URI, ce qui est clair, cohérent, moins bogué et sans aucun problème. Surtout si vous créez une application qui va bien au-delà du simple CRUD, RPC est la seule solution. J'ai un autre problème avec les puristes RESTful: HTTP POST, GET, PUT, DELETE ont des significations définies dans HTTP qui ont été subverties par REST en signifiant autre chose, simplement parce qu'elles correspondent la plupart du temps - mais pas toutes du temps.

En programmation, il y a longtemps que j'ai constaté qu'essayer d'utiliser une chose pour signifier deux choses va arriver un jour et vous mordre. J'aime pouvoir utiliser POST pour à peu près toutes les actions car il offre la liberté d'envoyer et de recevoir des données en fonction des besoins de votre méthode. Vous ne pouvez pas adapter le monde entier à CRUD.

155
Bruce Patin

Tout d'abord, HTTP-REST est une architecture de "transfert d'état représentatif". Cela implique beaucoup de choses intéressantes:

  • Votre API sera sans état et donc beaucoup plus facile à concevoir (il est très facile d'oublier une transition dans un automate complexe) et à intégrer des composants logiciels indépendants.
  • Vous serez amené à concevoir des méthodes de lecture comme sûres , faciles à mettre en cache et à intégrer.
  • Vous serez amené à concevoir des méthodes d’écriture comme idempotentes , qui traiteront beaucoup mieux les délais d’expiration.

Deuxièmement, HTTP-REST est entièrement compatible avec HTTP (voir "safe" et "idempotent" dans la partie précédente), vous pourrez donc réutiliser des bibliothèques HTTP (existantes pour chaque langue existante) et des serveurs proxy inversés HTTP, ce qui vous donnera la possibilité d'implémenter des fonctionnalités avancées (cache, authentification, compression, redirection, réécriture, journalisation, etc.) avec zéro ligne de code.

Enfin, utiliser HTTP comme protocole RPC est une énorme erreur selon le concepteur de HTTP 1.1 (et inventeur de REST): http://www.ics.uci.edu/~fielding/pubs/ dissertation/evaluation.htm # sec_6_5_2

27
Aurélien

Excellentes réponses - je voulais juste clarifier certains des commentaires. JSON-RPC est rapide et facile à utiliser, mais comme indiqué précédemment, les ressources et les paramètres sont étroitement liés et il a tendance à s'appuyer sur des verbes (api/deleteUser, api/addUser) utilisant GET/POST where-as REST fournit des ressources faiblement couplées (api/utilisateurs) qui, dans une API HTTP REST, reposent sur plusieurs méthodes HTTP (GET, POST, PUT, PATCH, DELETE). REST est un peu plus difficile à implémenter pour les développeurs inexpérimentés, mais le style est devenu assez courant et il offre beaucoup plus de flexibilité à long terme (prolongeant la durée de vie de votre API).

En plus de ne pas avoir de ressources étroitement couplées, REST vous permet également d'éviter de vous engager dans un seul type de contenu. Cela signifie que votre client doit recevoir les données au format XML, JSON ou même YAML, si intégré à votre système, vous pouvez renvoyer n'importe lequel de ceux qui utilisent les en-têtes content-type/accept.

Cela vous permet de garder votre API suffisamment souple pour prendre en charge les nouveaux types de contenu OR exigences du client.

Mais ce qui différencie vraiment REST de JSON-RPC, c'est qu'il respecte une série de contraintes soigneusement élaborées, garantissant une flexibilité architecturale. Ces contraintes consistent notamment à s'assurer que le client et le serveur peuvent évoluer indépendamment l'un de l'autre (vous pouvez effectuer des modifications sans gâcher l'application de votre client), les appels sont sans état (l'état est représenté par l'hypermédia), une interface uniforme est fournie pour les interactions, L'API est développée sur un système en couches et la réponse peut être mise en cache par le client. Il existe également une contrainte optionnelle pour fournir du code à la demande.

Cependant, tout ceci étant dit, les API MOST ne sont pas RESTful (selon Fielding) car elles n'incorporent pas d'hypermédia (liens hypertextes incorporés dans la réponse permettant de naviguer dans l'API). La plupart des API que vous découvrirez ressemblent à REST dans la mesure où elles suivent la plupart des concepts de REST, mais ignorent cette contrainte. Cependant, de plus en plus d'API implémentent cette fonctionnalité et cela devient de plus en plus une pratique courante.

Cela vous donne également une certaine souplesse puisque des API hypermédia (telles que Stormpath) dirigent le client vers les URI (ce qui signifie que si quelque chose change, dans certains cas, vous pouvez modifier l’URI sans impact négatif), où-comme avec les URI RPC doivent être statiques. Avec RPC, vous aurez également besoin de documenter de manière détaillée ces différents URI et d’expliquer comment ils fonctionnent les uns par rapport aux autres.

En général, je dirais que REST est la voie à suivre si vous souhaitez créer une API extensible et flexible, qui durera longtemps. Pour cette raison, je dirais que c'est la voie à suivre 99% du temps.

Bonne chance, Mike

23
Mike Stowe

OMI, le point clé est l’orientation action par rapport aux ressources. REST est axé sur les ressources et convient parfaitement aux opérations CRUD. Compte tenu de sa sémantique connue, il offre une certaine prévisibilité à un premier utilisateur. Toutefois, lorsqu'il est implémenté à partir de méthodes ou de procédures, vous obligez à fournir une traduction artificielle au monde centré sur les ressources. D'autre part, RPC convient parfaitement aux API orientées action, dans lesquelles vous exposez des services, et non des ensembles de ressources CRUD.

Nul doute que REST est plus populaire, cela ajoute certainement des points si vous souhaitez exposer l'API à un tiers.

Si ce n'est pas le cas (par exemple, en cas de création d'un frontal AJAX dans un SPA), mon choix est RPC. En particulier, JSON-RPC, associé à JSON Schema en tant que langage de description et transporté via HTTP ou Websockets en fonction du cas d'utilisation.

JSON-RPC est une spécification simple et élégante qui définit les charges utiles JSON de demande et de réponse à utiliser dans un RPC synchrone ou asynchrone.

JSON Schema est une spécification préliminaire définissant un format basé sur JSON destiné à décrire les données JSON. En décrivant vos messages d'entrée et de sortie de service à l'aide de JSON Schema, vous pouvez avoir une complexité arbitraire dans la structure du message sans compromettre la convivialité, et l'intégration de service peut être automatisée.

Le choix du protocole de transport (HTTP vs websockets) dépend de différents facteurs, le plus important étant si vous avez besoin de fonctionnalités HTTP (mise en cache, revalidation, sécurité, idempotence, type de contenu, multipart, ...) ou si votre application doit être échangée. messages aux hautes fréquences.

Jusqu’à présent, c’est vraiment mon opinion personnelle sur la question, mais c’est quelque chose qui peut être très utile pour les développeurs Java qui lisent ces lignes, le cadre sur lequel je travaille depuis un an, né de la même question. vous vous demandez maintenant:

http://rpc.brutusin.org

Vous pouvez voir une démonstration en direct ici, montrant le navigateur de référentiel intégré pour les tests fonctionnels (grâce au schéma JSON) et une série d'exemples de services:

http://demo.rpc.brutusin.org

J'espère que ça aide mon pote!

Nacho

17
idelvall

Si votre service fonctionne correctement avec uniquement des modèles et le modèle GET/POST/PUT/DELETE, utilisez REST pur.

Je conviens que HTTP est conçu à l'origine pour les applications sans état.

Mais pour les applications Web (temps réel) plus complexes (!) En temps réel où vous voudrez utiliser Websockets (ce qui implique souvent un état de mémoire), pourquoi ne pas utiliser les deux? JSON-RPC over Websockets étant très léger, vous bénéficiez des avantages suivants:

  • Mises à jour instantanées sur chaque client (définissez votre propre appel RPC de serveur à client pour la mise à jour des modèles)
  • Facile d'ajouter de la complexité (essayez de faire un clone Etherpad avec seulement REST)
  • Si vous le faites correctement (ajoutez RPC uniquement en tant que supplément pour le temps réel), la plupart sont encore utilisables avec uniquement REST (sauf si la fonction principale est un chat ou quelque chose du genre).

Comme vous ne concevez que l'API côté serveur, commencez par définir les modèles REST, puis ajoutez le support JSON-RPC selon vos besoins, en limitant au minimum le nombre d'appels RPC.

(et désolé pour abus de parenthèses)

16
flo

J'ai été un grand fan de REST par le passé et il présente de nombreux avantages par rapport à RPC sur papier. Vous pouvez présenter au client différents types de contenu, la mise en cache, la réutilisation des codes d'état HTTP, vous pouvez guider le client à travers l'API et vous pouvez intégrer de la documentation dans l'API si, de toute façon, elle ne s'explique pas elle-même.

Mais mon expérience m'a montré qu'en pratique, cela ne tient pas et que vous faites plutôt beaucoup de travail inutile pour que tout soit correct. De plus, les codes de statut HTTP ne correspondent souvent pas à la logique de votre domaine et leur utilisation dans votre contexte est souvent un peu forcée. Mais le pire aspect de REST à mon avis est que vous passez beaucoup de temps à concevoir vos ressources et les interactions qu’elles permettent. Et chaque fois que vous apportez des ajouts majeurs à votre API, vous espérez trouver la bonne solution pour ajouter la nouvelle fonctionnalité et vous ne vous êtes pas déjà isolé.

Cela me fait souvent penser à une perte de temps, car la plupart du temps, je sais déjà parfaitement comment modéliser une API comme un ensemble d'appels de procédure à distance. Et si j’ai réalisé tous ces efforts pour modéliser mon problème dans les contraintes de REST, le problème suivant est de savoir comment l’appeler depuis le client. Nos programmes sont basés sur des procédures d'appel. Il est donc facile de créer une bonne bibliothèque client RPC, de construire une bonne bibliothèque client REST moins souvent et dans la plupart des cas, il vous suffira de mapper votre API REST sur le serveur. à un ensemble de procédures de votre bibliothèque client.

Pour cette raison, RPC me semble aujourd'hui beaucoup plus simple et plus naturel. Ce qui me manque vraiment, c’est un cadre cohérent qui facilite l’écriture de services RPC auto-descriptifs et interopérables. Par conséquent, j'ai créé mon propre projet pour expérimenter de nouvelles façons de rendre RPC plus facile pour moi-même et peut-être que quelqu'un le trouve utile aussi: https://github.com/aheck/reflectrpc

15
ahe

Selon le modèle de Richardson , la question n'est pas REST vs RPC , mais combien de REST ?

Dans cette vue, la conformité à la norme REST peut être classée en 4 niveaux.

  • niveau 0: penser en termes d'actions et de paramètres. Comme l'explique l'article, , cela équivaut essentiellement à JSON-RPC (l'article l'explique pour XML-RPC, mais les mêmes arguments sont valables pour les deux).
  • niveau 1: penser en termes de ressources. Tout ce qui concerne une ressource appartient à la même URL
  • niveau 2: utilise les verbes HTTP
  • niveau 3: HATEOAS

Selon le créateur de la norme REST, seuls les services de niveau 3 peuvent être appelés RESTful. Cependant, il s'agit d'une métrique de conformité , pas de qualité. Si vous souhaitez simplement appeler une fonction distante qui effectue un calcul, il ne sert probablement à rien d'avoir des liens hypermédia pertinents dans la réponse, ni de différencier les comportements en fonction du verbe HTTP utilisé. Ainsi, un tel appel a intrinsèquement tendance à ressembler davantage à RPC. Cependant, un niveau de conformité plus bas ne signifie pas nécessairement un état d’état ou un couplage plus élevé. Probablement qu'au lieu de penser REST vs RPC , vous devriez utiliser autant que possible REST, mais pas plus. Ne modifiez pas votre application uniquement pour respecter les normes de conformité RESTful.

11
blue_note

Pourquoi JSON RPC:

Dans le cas de REST apis, nous devons définir un contrôleur pour chaque fonctionnalité/méthode dont nous pourrions avoir besoin. En conséquence, si nous voulons que 10 méthodes soient accessibles à un client, nous devons écrire 10 contrôleurs pour interfacer la requête du client avec une méthode particulière.

Un autre facteur est que, même si nous avons différents contrôleurs pour chaque méthode/fonctionnalité, le client doit se rappeler s’il faut utiliser POST ou GET. Cela complique davantage les choses. En plus de cela pour envoyer des données, il faut définir le type de contenu de la demande si POST est utilisé.

Dans le cas de JSON RPC, les choses sont grandement simplifiées car la plupart des serveurs JSONRPC fonctionnent sur POST HTTP et le type de contenu est toujours application/json. Cela vous évite de penser à utiliser la méthode HTTP et les paramètres de contenu appropriés côté client.

Il n'est pas nécessaire de créer des contrôleurs distincts pour les différentes méthodes/fonctionnalités que le serveur souhaite exposer à un client.

Pourquoi REST:

Vous avez des URL distinctes pour les différentes fonctionnalités que le serveur souhaite exposer au côté client. En conséquence, vous pouvez intégrer ces URL.

La plupart de ces points sont discutables et dépendent entièrement du besoin d'une personne.

6
Umer Farooq

Je pense que, comme toujours, ça dépend ...

REST a l'immense avantage d'un large soutien du public, ce qui signifie beaucoup d'outils et de livres. Si vous avez besoin de créer une API qui est utilisée par un grand nombre de consommateurs de différentes organisations, c'est la solution à suivre pour une seule raison: elle est populaire. En tant que protocole, il s’agit bien entendu d’un échec total, car il existe trop de façons complètement différentes de mapper une commande sur une adresse URL/verbe/réponse.

Par conséquent, lorsque vous écrivez une application Web d'une seule page qui a besoin de parler à un serveur, je pense que REST est beaucoup trop complexe. Dans cette situation, vous n'avez pas à vous soucier de la compatibilité à long terme car l'application et l'API peuvent évoluer ensemble.

Une fois, j'ai commencé avec REST pour une application Web d'une seule page, mais les commandes à granularité fine entre l'application Web et le serveur m'ont rapidement rendu fou. Dois-je le coder comme paramètre de chemin? Dans le corps? Un paramètre de requête? Un en-tête? Après la conception URL/Verb/Response, j'ai ensuite dû coder ce désordre en Javascript, le décodeur dans Java, puis appeler la méthode réelle. Bien qu'il existe de nombreux outils, il est très difficile de ne pas obtenir de sémantique HTTP dans le code de votre domaine, ce qui est une très mauvaise pratique. (Cohésion)

Essayez de créer un fichier Swagger/OpenAPI pour un site moyennement complexe et comparez-le à une seule interface Java décrivant les procédures distantes de ce fichier. L'augmentation de la complexité est stupéfiante.

J’ai donc passé de REST à JSON-RPC pour l’application Web à page unique. aI a développé une petite bibliothèque qui a codé une interface Java sur le serveur et l'a livrée au navigateur. Dans le navigateur, cela créait un proxy pour le code de l'application qui renvoyait une promesse pour chaque fonction.

Encore une fois, REST a sa place juste parce qu'il est célèbre et donc bien soutenu. Il est également important de reconnaître la philosophie sous-jacente des ressources sans état et le modèle hiérarchique. Cependant, ces principes peuvent tout aussi bien être utilisés dans un modèle RPC. JSON RPC fonctionne sur HTTP et présente donc les mêmes avantages que REST dans ce domaine. La différence est que lorsque vous rencontrez inévitablement des fonctions qui ne correspondent pas à ces principes, vous n'êtes pas obligé de faire beaucoup de travail inutile.

2
Peter Kriens

Il serait préférable de choisir JSON-RPC entre REST et JSON-RPC pour développer une API pour une application Web plus facile à comprendre. JSON-RPC est préférable car sa correspondance avec les appels de méthode et les communications peut être facilement comprise.

Le choix de l'approche la mieux adaptée dépend des contraintes ou de l'objectif principal. Par exemple, dans la mesure où la performance est un trait majeur, il est conseillé d’utiliser JSON-RPC (par exemple, le calcul hautes performances). Cependant, si l'objectif principal est d'être agnostique afin de proposer une interface générique pouvant être inférée par d'autres, il est conseillé de choisir REST. Si vous devez atteindre vos deux objectifs, il est conseillé d’inclure les deux protocoles.

Le fait qui divise REST de JSON-RPC est qu’il est suivi d’une série de contraintes soigneusement élaborées, qui confirment la flexibilité architecturale. Les contraintes impliquent que le client et le serveur puissent se développer indépendamment l'un de l'autre (des changements peuvent être apportés sans gâcher l'application du client), les appels sont sans état (l'état est considéré comme un hypermédia), un uniforme l'interface est proposée pour les interactions, l'API est avancée sur un système en couches (Hall, 2010). JSON-RPC est rapide et facile à utiliser. Toutefois, comme indiqué, les ressources et les paramètres sont étroitement liés et dépendent probablement des verbes (api/addUser, api/deleteUser) à l'aide de GET/POSTREST fournit des ressources faiblement couplées (api/utilisateurs) dans un HTTP. REST L'API dépend de plusieurs méthodes HTTP telles que GET, PUT, POST, DELETE, PATCH. REST est un peu plus difficile à mettre en œuvre par les développeurs inexpérimentés.

JSON (noté JavaScript Object Notation) étant un format léger d'échange de données, il est facile à lire et à écrire pour les humains. Il est facile pour les machines d'analyser et de générer. JSON est un format de texte totalement indépendant des langages, mais qui respecte les conventions connues des programmeurs de la famille des langages: C #, C, C++, Java, Perl, JavaScript, Python et de nombreux autres. De telles propriétés font de JSON un langage d'échange de données parfait et un meilleur choix.

1
SinghKunal

Mauvaise question: impose un manichéen qui n'existe pas!

Vous pouvez utiliser JSON-RPC avec "less verbe" (no method ) et conserver la standardisation minimale nécessaire pour sendo id, paramètres, error codes et warning messages. La norme JSON-RPC ne dit pas "vous ne pouvez pas être REST", mais expliquez seulement comment créer des informations de base.

"REST JSON-RPC" existe ! est REST avec les "meilleures pratiques", pour un stockage minimal des informations, avec des contrats simples et solides.


Exemple

(de cette réponse et contexte didactique)

Lorsqu'il s'agit de REST, il est généralement utile de commencer par penser en termes de ressources. Dans ce cas, la ressource n'est pas simplement un "compte bancaire" mais une transaction de ce compte bancaire ... Mais JSON-RPC n'oblige pas le paramètre "méthode", ils sont tous codés par le "chemin" du noeud final.

  • REST Deposit avec POST /Bank/Account/John/Transaction avec une demande JSON {"jsonrpc": "2.0", "id": 12, "params": {"currency":"USD","amount":10}}.
    La réponse JSON peut être quelque chose comme {"jsonrpc": "2.0", "result": "sucess", "id": 12}

  • REST Withdraw avec POST /Bank/Account/John/Transaction ... similaire.

  • ... GET /Bank/Account/John/Transaction/12345@13 ... Cela pourrait renvoyer un enregistrement JSON de cette transaction exacte (par exemple, vos utilisateurs veulent généralement un enregistrement des débits et des crédits sur leur compte). Quelque chose comme {"jsonrpc": "2.0", "result": {"debits":[...],"credits":[...]}, "id": 13}. La convention relative à la requête (REST) ​​GET peut inclure le code d'identification de "@id", il n'est donc pas nécessaire d'envoyer de JSON, mais vous utilisez toujours JSON-RPC dans le pack de réponses.

1
Peter Krauss

REST est étroitement associé à HTTP. Par conséquent, si vous n'exposez votre API que via HTTP, alors REST convient mieux à la plupart des situations (mais pas à toutes). Toutefois, si vous devez exposer votre API sur d'autres transports, tels que la messagerie ou les sockets Web, alors REST n'est tout simplement pas applicable.

1
dtoux

Si vous demandez des ressources, l’API RESTful est préférable par conception. Si vous demandez des données complexes avec beaucoup de paramètres et des méthodes compliquées autres que le simple CRUD, alors RPC est la bonne solution.

0
Adrian Liu

J'utilise vdata pour le protocole RPC: http://vdata.dekuan.org/

1, PHP et JavaScript sont corrects. 2, l'appel CORS (Cross-Origin Resource Sharing) est toujours correct.

0
Liu Qixing

Je pense qu'il y a un point que les gens ont oublié de mentionner. Si vous avez déjà une application Web, alors REST est souhaitable, car vous aurez de toute façon besoin du serveur d'applications et vous pouvez sécuriser les deux à l'aide de https ... mais si vous ne possédez pas d'application Web ( RPC est souhaitable, car vous n’avez plus besoin de configurer un serveur d’applications et de le configurer à la hâte. En dehors de cela, je ne vois aucun avantage fondamental réel dans l'un ou l'autre.

0
max