2010-03-09 8 views
1

Imaginez une sorte d'application bancaire, avec un écran pour créer des comptes. Chaque compte a Monnaie et une banque comme une propriété, Monnaie étant une catégorie distincte, ainsi que la Banque . Le code pourrait ressembler à ceci:Limiter le nombre d'appels de service dans une application RESTful

public class Account 
{ 
    public Currency Currency { get; set; } 
    public Bank Bank { get; set; } 
} 

public class Currency 
{ 
    public string Code { get; set; } 
    public string Name { get; set; } 
} 

public class Bank 
{ 
    public string Name { get; set; } 
    public string Country { get; set; } 
} 

Selon les principes de conception REST, chaque ressource dans l'application devrait avoir son propre service, et chaque service doit avoir des méthodes qui tracent bien les verbes HTTP. Donc, dans notre cas, nous avons un AccountService, CurrencyService et BankService. Dans l'écran de création d'un compte, nous avons une interface utilisateur pour sélectionner la banque dans une liste de banques et pour sélectionner une devise dans une liste de devises. Imaginez que c'est une application web, et ces listes sont des listes déroulantes. Cela signifie qu'une liste déroulante est renseignée à partir de CurrencyService et une à partir de BankService. Cela signifie que lorsque nous ouvrons l'écran de création d'un compte, nous devons faire deux appels de service à deux services différents. Si cet écran n'est pas en lui-même sur une page, il peut y avoir plus d'appels de service de la même page, ce qui a un impact sur les performances. Est-ce normal dans une telle application? Sinon, comment peut-on l'éviter? Comment le design peut-il être modifié sans quitter REST?

Répondre

2

Il est une décision architecturale que vous devez baser sur la taille et la complexité de votre système. Plus votre système est grand/complexe, plus il est susceptible de bénéficier de niveaux croissants de séparation/encapsulation (par exemple, vous pouvez trouver que BankService doit évoluer plus rapidement que CurrencyService, et l'exécution séparée de ces services vous permettra de le faire). Ce que je voudrais souligner en réponse à votre question, cependant, est que vous devriez considérer mettre en cache les résultats de ces appels de service et réutiliser le résultat, plutôt que de rappeler le service pour chaque chargement de page. Si (comme les noms le suggèrent) le résultat de CurrencyService et BankService ne changera probablement pas très souvent, vous pouvez les mettre en cache pendant des minutes ou des heures à la fois et ne pas avoir à faire ces appels à plusieurs reprises. Si votre application est occupée (c'est-à-dire si vous pensez en termes de hits par seconde plutôt que de hits par heure), cela peut vous économiser de la mémoire à l'exécution car le résultat d'un seul appel de service est partagé entre plusieurs demandes de page (plutôt que chaque page ayant besoin d'obtenir le jeu de résultats séparément).

+0

Oui, vous avez raison. La mise en cache sur le client résoudrait cela. Mais en tant que concept, le style architectural ne dépend pas de la mise en cache et a toujours cette limitation pratique. Je me demandais s'il y avait un changement de conception qui pourrait résoudre le problème. – Slavo

+0

Si vous êtes strictement RESTful, alors la banque et la devise doivent avoir des URI différentes, car ce sont des entités différentes. Mais rien ne vous empêche de créer un service (en lecture seule) qui pourrait renvoyer les deux listes en une seule entité. Cela dit, vous finirez par avoir besoin de tels services pour tous les autres écrans, et votre design en souffrira. En fin de compte, le coût minime du perf est le prix d'une architecture REST bien encapsulée (tout comme vous payez un minuscule succès pour plusieurs DLL par rapport à un mammouth .exe, ou pour des appels de méthode vs code inline). Cela ne devrait pas être la plus grande préoccupation que vous avez en termes de performance. :-) –

+0

D'accord, je suppose que c'est le meilleur que j'aurai. Merci :). limite d'upvote atteinte, de retour demain. – Slavo

2

c'est normal et ne peut être évité ... ... sauf si vous créez un service spécifique qui renvoie toutes les données d'un écran spécifique en une fois.

Ceci est l'un des aspects négatifs de l'approche REST - essentiellement si vous traitez des requêtes d'objet, et vous avez besoin de listes d'objets x, alors vous avez des appels x. Point.

Ce qui signifie que les conceptions REST ont une évolutivité limitée à ce niveau.

Encore une fois, comme au début - vous pouvez toujours avoir un service spécifique renvoyant toutes les données dont vous avez besoin sur un formulaire complexe en un seul appel.

+0

Comment puis-je implémenter un service qui renvoie plusieurs ensembles de résultats (sachant qu'il n'est pas RESTful)? Si j'utilise JSON, quelle serait la réponse et comment puis-je la gérer sur le client? – Slavo

+0

Désolé, mais il est tout à fait faux que vous ayez besoin d'effectuer des appels N pour récupérer une liste de N éléments. Si vous avez besoin d'une vue spécialisée dans votre application pour une raison quelconque (par exemple, une liste complète d'éléments dans une vue unique), définissez simplement une ressource qui a la sémantique appropriée. TomTom, s'il vous plaît ne faites pas de déclarations sur REST qui ne sont pas vraies. –

+0

@Jan, ce n'est pas N appels pour N éléments. C'est plutôt N appels pour M éléments, où N est le nombre de ressources dont vous avez besoin d'une liste de, M est le nombre d'éléments dans une liste. – Slavo

1

Accrochez-vous, ReST consiste à représenter des ressources.

Je ne pense pas que vous devriez être trop stricte sur les points suivants:

Selon les principes de conception REST, chaque ressource dans l'application devrait avoir son propre service, et chaque service doit avoir des méthodes qui cartographient joliment aux verbes HTTP.

Il devrait être parfaitement bien que la ressource que vous représentez dans le navigateur est un "formulaire" et contient toutes les informations pertinentes. Pensez au bon degré d'abstraction lorsque vous définissez votre structure d'URL.

+0

Dans certains cas non apparentés, j'ai également besoin d'appels séparés pour les objets séparés (c'est-à-dire seulement une liste de banques), donc je ne peux pas prendre le formulaire en tant que ressource. Ou au moins, ce serait beaucoup encombrant et sale. – Slavo

+1

Suggère que vous jetez un oeil à certains millésime Joe Gregorio: http://www.xml.com/pub/at/34 –

+0

"Pensez juste au bon degré d'abstraction" juste ongles. Bien que je dirais "en définissant vos ressources" et non "structure d'URL". –

0

Slavo,

il n'y a pas besoin de fournir différents services pour différentes ressources. En général, vous devez simplement fournir les opinions qui aident vos clients à atteindre leurs objectifs.Si l'un de ces points de vue est une «grande» vue (ressource) intégrée, y compris toutes les banques et les devises, alors c'est bien. Vous pouvez toujours fournir des vues détaillées (ressources) pour la création et l'édition de banques et de devises.

Si les banques et les devises sont fournies par différentes applications Web et que vous avez besoin du client pour résoudre les références, gardez à l'esprit que les pages HTML le font tout le temps avec des images en ligne. La mise en cache permet de réduire le nombre d'appels réseau dans de tels scénarios (et la liste des banques et des devises ne semble pas très volatile).

(Voir http://www.nordsc.com/blog/?p=152)

Exemple:


GET /service/account-management 

200 Ok 
Content-Type: application/vnd.my.accounting 
<page> 
... 
<banklist href="http://other.org/service/banklist" type="application/atom+xml" /> 
<currencylist href="http://standard.org/currencies" type="application/rss+xml" /> 
... 
</page> 

Les demandes de sous à banklist et currencylist doit être servi de cache privé la plupart du temps du client.

Jan

+0

L'édition/insertion de banques et de devises ne se passe pas dans la même vue, donc ce n'est pas pertinent. Autant que je comprenne, vous dites qu'il est normal que ma ressource soit le formulaire et que la réponse du service soit une liste de devises et une liste de banques. Si oui, la question devient, comment puis-je retourner plusieurs ensembles de résultats, comme je l'ai demandé dans le commentaire à la réponse de TomTom. – Slavo

+0

Concevez simplement toutes les ressources dont vous avez besoin pour activer ce que vous voulez activer. Il n'y a pas de problème s'ils se chevauchent. Si vous voulez qu'une ressource représente plusieurs ensembles de résultats, faites-le comme ça. –