Exporter (0) Imprimer
Développer tout

Conception du contrat

Scott Seely
Microsoft Corporation

Avant-propos

Cela fait longtemps que nous ne nous sommes pas adressés à vous par le biais de la rubrique À votre service. Pour remédier à cette situation, nous mettons en place une équipe sur le projet : Matt Powell et Scott Seely. Permettez-moi de me présenter le premier. Je suis Scott. Mary Kirtland a déjà parlé de nous il y a un certain temps dans l'article Apprenons à nous connaître Lien non MSDN France Site en anglais. Cependant, nous aimerions nous présenter de manière un peu plus détaillée, maintenant que nous serons régulièrement présents dans cet espace.

Matt travaille chez Microsoft depuis plus de 10 années, dont la majeure partie à l'organisation du support aux développeurs de Microsoft (Microsoft's Developer Support Organization). Il insiste sur le fait qu'il est un spécialiste des protocoles réseau, puisqu'il a eu l'occasion de toucher à tous les protocoles : DLC, NetBIOS, Winsock, RPC, SNMP, WinInet et ISAPI. Matt préfère l'invite MS-DOS à l'Explorateur Windows® et peut à tout instant utiliser EDLIN pour modifier un fichier texte. Pendant ses heures de loisirs, Matt aime emmener sa famille (tous les 9) à des matches des Seattle Mariners. Il est l'un de ceux qui se trouvent au premier rang, juste derrière Ichiro, et qui agitent un mouchoir blanc.

Si vous avez lu les informations sur les coulisses de cette rubrique, vous aurez noté que l'un des membres de notre équipe, James Francisco, a mentionné le fait que, si le planning n'était pas respecté, c'était tout simplement parce que la moitié des développeurs (dont moi) était en congés de paternité. Le 15 mars, ma fille Angeline est née. Pendant quatre semaines, sa mère, son grand frère et moi-même nous sommes consacrés à faire connaissance avec ce nouveau membre de notre famille. J'ai également profité de ce temps-là pour terminer mon livre sur SOAP pour Prentice Hall, SOAP: Cross Platform Web Service Development Using XML. Il devrait être dans les rayonnages des librairies vers juillet 2001. Outre l'écriture, je suis également le spécialiste des solutions inter-plates-formes. Pourquoi ? Parce qu'il se trouve que j'ai utilisé trois kits d'outils SOAP non Microsoft : le mien SimpleSOAP, ainsi que Apache SOAP Lien non Microsoft Site en anglais et SOAP::Lite Lien non Microsoft Site en anglais.

Présentation

Dans cette rubrique, nous allons examiner ce que vous devez prendre en compte lorsque vous concevez le contrat de votre service Web. Nous espérons que, lorsque vous songez à un service Web, vous ne vous limitez plus à des choses telles que la simple récupération des cours de la bourse ou l'obtention des températures dans votre ville. Vous devez envisager les services Web comme des composants avec des API riches en fonctionnalités. Dans cette article, nous étudions la conception de l'interface du service Web ainsi que tous les besoins liés à l'internationalisation.

Définition de l'interface vers le service Web

Aujourd'hui, pour expliquer aux autres comment atteindre et utiliser un service Web, nous utilisons un fichier de langage de description de services Web (WSDL, Web Services Description Language). Lorsque SOAP a été lancé pour la première fois, plusieurs langages de description d'interface (IDL) basés sur le XML ont vu le jour. Tous ces IDL reconnaissaient différentes manières de décrire un service et intégraient des éléments spécifiques à l'implémentation SOAP à laquelle ils étaient liés. Le besoin de normaliser s'est rapidement fait sentir et WSDL est apparu. WSDL décrit les éléments suivants :

  1. Les types de données reconnus par le service Web
  2. Le schéma des messages
  3. La méthode d'échange utilisée par le service Web (requête/réponse, sens unique, diffusion de groupe, et ainsi de suite)
  4. L'emplacement du service Web
  5. Les informations d'erreur
  6. Les informations d'en-tête

Une description complète du langage WSDL dépasserait notre propos mais, à la fin de cet article, vous trouverez des liens vers d'excellentes notes documentaires sur le WSDL. Pour l'instant en revanche, je souhaite me concentrer sur l'utilisation des éléments ci-dessus pour définir votre interface vers le service Web.

Lorsque vous définissez votre interface, vous devez d'abord vous pencher sur vos types de données. Assurez-vous toujours que vos types peuvent être reconvertis en types de données de schéma XML. Par exemple, pour les chaînes, vous devez utiliser xsd:string. Lorsque vous construisez des types complexes, assurez-vous qu'ils finissent par se décomposer en l'un des types de données de schéma XML prédéfinis. Vous pouvez définir un contact, par exemple en indiquant l'adresse électronique et le numéro de téléphone professionnel. La section des types du fichier WSDL ressemblerait à ceci :

<definitions xmlns:s="http://www.w3.org/2001/XMLSchema" 
 xmlns:s0="http://tempuri.org/" 
 targetNamespace="http://tempuri.org/" 
 xmlns="http://schemas.xmlsoap.org/wsdl/">
 <types>
 <s:schema attributeFormDefault="qualified" 
 elementFormDefault="qualified" 
 targetNamespace="http://tempuri.org/">
 <s:element name="ContactInfo">
 <s:complexType>
  <s:sequence>
  <s:element minOccurs="1" maxOccurs="1" 
  name="name" nillable="true" 
  type="s0:PersonName" />
  <s:element minOccurs="1" maxOccurs="1" 
  name="emailAddress" nillable="true" 
  type="s0:EmailAddress" />
  <s:element minOccurs="0" maxOccurs="unbounded" 
  name="phoneNumbers" nillable="true" 
  type="s0:PhoneNumber" />
  </s:sequence>
 </s:complexType>
 </s:element>
 <s:complexType name="PersonName">
 <s:sequence>
  <s:element minOccurs="1" maxOccurs="1" name="first"
  nillable="false" type="s:string" />
  <s:element minOccurs="1" maxOccurs="1" 
  name="middle" nillable="true" 
  type="s:string" />
  <s:element minOccurs="1" maxOccurs="1" name="last"
  nillable="false" type="s:string" /> 
 </s:sequence>
 </s:complexType>
 <s:complexType name="PhoneNumber">
 <s:sequence>
  <s:element minOccurs="1" maxOccurs="1" 
  name="areaCode" nillable="false" 
  type="s:long" />
  <s:element minOccurs="1" maxOccurs="1" name="prefix"
  nillable="true" type="s:long" />
  <s:element minOccurs="1" maxOccurs="1" name="suffix"
  nillable="false" type="s:long" />
 </s:sequence>
 </s:complexType>
 </s:schema>
 </types>
 ...
</definitions>

Comme vous pouvez le voir, tous les types complexes finissent par se réduire à un type de données de schéma XML existant. En utilisant cette structure, vous augmentez la probabilité que d'autres implémentations SOAP soient capables d'interagir avec votre service Web. Pourquoi ? Parce qu'il existe de nombreuses implémentations de schéma XML pour de nombreuses plates-formes ; en vous conformant aux normes et en évitant les modifications de votre implémentation préférée, vous accroissez la possibilité d'utilisation de votre service Web.

Ensuite, vous vous demanderez comment structurer la fonctionnalité de votre service Web. Lors de la programmation d'un service Web, groupez les opérations liées sur un port unique. Pour le service des Favoris, nous avons décomposé la conception en trois services :

  • Connexion : authentifie les détenteurs de licence et leur accorde une clé à utiliser lors de l'accès au service
  • Compte : gère la création des utilisateurs finaux et la maintenance des données de Favoris
  • Rapport : prend en charge la consignation

En divisant la fonctionnalité en blocs de fonctions liées, vous facilitez pour les utilisateurs du service Web la recherche des fonctions dont ils ont besoin lorsqu'ils travaillent sur une fonctionnalité en particulier. Les programmeurs sauront ensuite que la fonctionnalité liée fonctionne sur un port précis, ce qui leur facilite un peu la tâche.

L'implémentation de ces ports réside généralement à l'intérieur d'un objet. En interne, les objets peuvent partager des fonctions d'assistance commune. En externe, ces objets ne doivent pas reposer sur l'état interne. En observant les groupes de discussions, j'ai constaté que beaucoup de gens se sentent frustrés lorsqu'ils tentent de transmettre les pointeurs ou les références relatifs aux objets SOAP. Pourquoi cette frustration ? Parce que leur projet de conception requiert une référence au pointeur et qu'ils réalisent rapidement que SOAP ne permet pas cela.

Si vous êtes coincés, il existe une excellente échappatoire : les paramètres in/out. Qu'un objet soit un paramètre in, out ou in/out, il doit pouvoir écrire son état dans le XML. Lorsque vous spécifiez la partie de l'objet dont vous avez besoin, analysez les données dont la fonction a réellement besoin et demandez uniquement ces informations. Ceci peut faire une différence considérable car la transmission de données par le réseau peut prendre plus de temps que la totalité du processus de sérialisation. Plus le message est petit, moins il prendra de temps à atteindre sa destination.

Vous souhaiterez également garder un œil sur les allers-retours des paramètres. Si vous utilisez un outil qui génère le WSDL pour vous, tel que le moteur d'exécution .NET ou l'outil WSDLGEN.EXE de SOAP Toolkit v2, vous n'êtes peut-être pas conscient que vous gaspillez de la bande passante. Pendant que vous travaillez sur la solution, prenez le temps d'observer à quoi ressemble le WSDL généré. Regardez si vous pouvez trouver des endroits pour épurer les messages qui vont et qui viennent. Par exemple, n'importe quel paramètre envoyé en tant que ByRef dans un objet COM Visual Basic® (ils sont tous ByRef si vous ne spécifiez rien) sera un paramètre in/out. Si vous utilisez l'objet mais que vous ne le modifiez pas avant le renvoi, changez plutôt ce paramètre en ByVal. De la même manière, inspectez les fichiers IDL à la recherche de vos objets C++ et assurez-vous que les paramètres sont décorés de manière appropriée.

La plupart du temps, votre service Web utilisera le RPC traditionnel requête/réponse. Vous pouvez spécifier la méthode à sens unique en omettant l'élément de sortie (output) de l'opération.

Requête/réponse :

<operation name='DeleteFavorite' parameterOrder='key Username FavID'>
 <input message='wsdlns:Account.DeleteFavorite' />
 <output message='wsdlns:Account.DeleteFavoriteResponse' />
</operation>

Sens unique :

<operation name='DeleteFavorite' parameterOrder='key Username FavID'>
 <input message='wsdlns:Account.DeleteFavorite' />
</operation>

Le message à sens unique omet simplement le message de sortie. Lorsque cela s'avère utile, omettez le message de sortie (output message). Ainsi, vous réduirez l'attente et le service semblera plus rapide au client car celui-ci n'attendra pas de message en retour.

WSDL étant un IDL, la seule exigence pour le code derrière le port WSDL est qu'il réponde correctement à toute requête SOAP. Que cela signifie-t-il pour vous ? Imaginez que vous êtes en train de travailler sur une application cliente qui s'adresse aux serveurs traitant les commandes. Un serveur peut fournir les commandes relatives aux meubles, un autre aux livres et un troisième aux DVD. En supposant que la seule différence entre ces systèmes est la base de données des éléments, vous pouvez utiliser le même client pour accéder à ces différents services. La seule différence doit être le point de terminaison du service (il s'agit de l'un des concepts sur lesquels l'UDDI Lien non Microsoft repose). La liaison SOAP du WSDL permet cela grâce à l'utilisation de l'élément soap:address.

<service name='Account' >
 <port name='AccountSoapPort' binding='wsdlns:AccountSoapBinding' >
 <soap:address location='http://coldrooster.com/ssf/account.asp' />
 </port>
</service>

Beaucoup de kits d'outils reconnaissant le WSDL vous permettent de changer le point de terminaison après lecture dans le fichier. Si vous connaissez l'emplacement des autres services qui implémentent le port, ou si vous utilisez un serveur UDDI pour obtenir des informations similaires, vous pouvez utiliser le même client pour communiquer avec différents points de terminaison.

En prenant un peu de temps pour réfléchir à votre interface SOAP, votre service Web devrait être accessible à partir de n'importe quelle machine. Si plusieurs sources offrent le même service, une interface commune permet à un client unique d'accéder à divers services Web. Lorsque vous concevez ces applications en utilisant des outils de génération de WSDL automatisés, prenez le temps d'examiner le WSDL généré et assurez-vous que vous n'envoyez que ce qui est absolument nécessaire. Pour les opérations brèves, vous vous apercevrez que le réseau est le goulet d'étranglement.

Internationalisation du service Web

Vous devrez également prendre en compte les types d'accès qui seront effectués vers le service Web. N'importe qui dans le monde pourra utiliser le service : qu'est-ce que cela implique pour vous ?

Vous aurez peut-être des problèmes de stockage et de transmission des données. Si votre service accepte les données sous forme de chaîne, assurez-vous que vous pouvez accepter, transmettre et stocker les alphabets internationaux (par exemple japonais, cyrillique, arabe, etc.). Avec le service Favoris, nous traitons cela en imposant au service qu'il accepte le XML codé en UTF-8 et en UTF-16. Microsoft® SOAP Toolkit v2 prend cela en charge pour vous. Vous devez également songer aux grands jeux de caractères lorsque vous concevez vos systèmes principaux. En arrière-plan, utilisez des types de chaîne et un stockage de données reconnaissant Unicode. Pour les Favoris, nous avons utilisé Visual Basic car il traite les chaînes Unicode en mode natif. Pour le stockage, nous stockons toutes nos chaînes dans Microsoft® SQL Server à l'aide des types de données nchar et nvarchar. Comme vous pouvez le constater, le fait de bien choisir ses outils peut faciliter l'implémentation de cet aspect de l'internationalisation.

Vous devez également réfléchir à la manière dont vous distribuez la documentation du service Web. La plupart des développeurs peuvent lire et écrire en anglais, ce qui vous permet d'ouvrir votre service à un maximum de personnes en fournissant une bonne documentation en anglais. Dans ces documents, n'utilisez pas de langage familier et utilisez un anglais aussi simple que possible. Pour améliorer l'acceptation de votre service dans d'autres pays, vous devrez peut-être songer à fournir une documentation rédigée dans la langue maternelle des développeurs.

Lors du renvoi des pannes SOAP, vous serez peut-être amené à autoriser les détenteurs de licence à spécifier une langue préférée pour le membre Fault.Description. Il est souvent préférable que l'utilisateur final du service puissent visualiser la majorité des erreurs. Nous avions envisagé un instant de fournir les chaînes d'erreur dans des langues en particulier mais nous avons finalement décidé de ne pas le faire (je sais que le groupe de projet Lucy aimerait traduire les chaînes d'erreur ; espérons, qu'il y aura un débat là-dessus dans leur équipe plus tard dans l'année). Au lieu de cela, nous avons rédigé la documentation en spécifiant les valeurs Fault.Code qui pourraient être renvoyées par chacune des fonctions présentées par le service Web sans exception. Ceci permet aux programmeurs d'implémenter eux-mêmes des applications qui utilisent le service Favoris pour traiter les erreurs et la localisation.

Vous devez également penser à ce que vous ferez si votre service Web devient populaire en dehors de votre propre région. Pour le moment, les services de Cold Rooster résident tous à Redmond (WA), aux États-Unis. Les utilisateurs hors du continent américain doivent recourir à un lien Internet transocéanique pour utiliser le service. Si le nombre d'utilisateurs dans ce cas l'avait justifié, nous aurions cherché à déployer les services Web dans d'autres pays du monde de sorte que les utilisateurs puissent obtenir des temps de réponse plus rapides. Avec des serveurs distribués partout dans le monde pour traiter les requêtes, de nouveaux problèmes surgissent. En premier lieu, en cas d'expansion du service Web, il nous faudra réfléchir sur la distribution des données utilisateur.

Pour le service Favoris, voici juste quelques-unes des questions qui se poseraient :

  • Les détenteurs de licence s'attendent à pouvoir accéder au service Web sur tous nos serveurs Web, ce qui implique que nous devrons élaborer des méthodes de synchronisation des données entre les centres de données.
  • Les utilisateurs finaux souhaitent que leurs données puissent voyager avec eux, où qu'ils aillent. Cela signifie que nous devons amener le détenteur de licence à se rappeler quel centre de données il doit contacter pour obtenir ses données utilisateur, ou bien que nous devons propager toutes les données utilisateur dans tous les centres de données.
  • Comment traiter les journaux d'audit lorsque les événements d'audit se produisent partout dans le monde ? Il est fort probable que nous allons stocker toutes les données d'audit dans une base de données, à un seul emplacement, et que nous allons simplement placer les requêtes vers cette source de données dans une file d'attente pour éviter tout problème de latence.
  • Nous devrons en outre élaborer des règles de résolution des conflits de modifications entre les centres de données disséminés à travers le monde. Par exemple, un détenteur de licence peut changer les données de contact administratif sur deux différents serveurs, auquel cas nous devrons alors appliquer des règles pour traiter le conflit.

Il existe un dernier élément, facile à cerner, relatif à l'internationalisation : définir les modes de paiement acceptés. Autoriserez-vous les utilisateurs à payer dans n'importe quelle devise ou leur demanderez-vous de payer dans votre devise locale ? Cet aspect de l'internationalisation peut constituer un problème complexe et nous le plaçons dans la boîte à idées pour un article futur, en fonction de l'intérêt que cela suscite chez nos lecteurs.

Conclusion

Lors de la conception d'un service Web, songez à la manière dont le service Web sera utilisé. Vous pouvez en optimiser les performances sur le réseau, si vous prenez un peu le temps d'examiner le fichier WSDL que vos outils génèrent pour vous. Ces fichiers vous aideront à repérer les endroits où vous transférez de grandes quantités de données qui peuvent nuire au débit global. En outre, évitez de placer toutes vos fonctionnalités dans un même panier, sauf si cela présente un intérêt particulier. Groupez les fonctions liées sur un port.

Lorsque vous pensez à l'internationalisation, essayez de concevoir pour un public aussi large que possible. Gardez à l'esprit que votre public parle plusieurs langues différentes. Concernant le service Favoris, nous l'avons testé pour nous assurer que nous pouvons stocker des chaînes dans une langue à alphabet étendu (comme le chinois par exemple). Vous devez procéder de même avec votre service Web. Identifiez toutes les chaînes pouvant se trouver en dehors des 128 premiers caractères ASCII et assurez-vous que vous pouvez stocker et récupérer des chaînes en chinois, arabe et autres alphabets. Ceci vous permet en outre de contrôler le traitement des chaînes Unicode.

Pour en savoir plus sur le WSDL, consultez les articles suivants :

Notes de documentation sur le WSDL :

Vous pouvez obtenir une liste complète des types de données XML déclarés sur la page XML Schema Part 2: Datatypes Lien non Microsoft Site en anglais.



Dernière mise à jour le lundi 10 septembre 2001



Microsoft réalise une enquête en ligne pour recueillir votre opinion sur le site Web de MSDN. Si vous choisissez d’y participer, cette enquête en ligne vous sera présentée lorsque vous quitterez le site Web de MSDN.

Si vous souhaitez y participer,
Afficher:
© 2014 Microsoft