SOAP ou REST : comment bien choisir

Cet article vous explique quand il est préférable de choisir des Web Services REST ou SOAP.

« Je dois mettre à jour ma base de données d’inventaire locale avec les informations des mes nombreux fournisseurs. Ces derniers permettent de s’interfacer avec des services Web. L’application n’ayant pas de composant côté serveur (il s’agit d’une client qui dialogue directement avec la base), est-il possible de consommer ces services Web directement depuis mon application ?

Vous avez déjà dû vous poser cette question. Ou même vous interroger sur une éventuelle solution à ce genre de problème. Jusqu’alors nous étions plutôt familier avec le fait de consommer un services Web qui rapporte les données, extraites de plusieurs sources, vers l’application.

Il existe une approche différente : la base de données agit comme le consommateur du service, et non pas, comme habituellement, comme le fournisseur de service. Cet article explique comment invoquer un service Web via les procédures stockées.

Les services Web

Globalement, un service Web est une méthode de communication entre deux applications ou appareils électroniques, via le Web. Il existe deux types de services Web: Simple Object Access Protocol (SOAP) et Representational State Transfer (REST).

SOAP est une spécification d’un protocole de communication standard (un ensemble de règles) pour l’ échange de messages XML. SOAP repose sur différents protocoles de transport, tels que HTTP et SMTP. L’usage du protocole standard HTTP permet au modèle SOAP de passer les paresseux et les proxies sans avoir à modifier le protocole. SOAP peut parfois être plus lent que des technologies middleware, comme CORBA ou ICE, à cause notamment du coté verbeux du format XML.

REST, quant à lui, décrit un ensemble de principes architecturaux par lesquels les données sont transmises sur une interface standard (telle que HTTP). REST ne contient une couche supplémentaire de messages et s’intéresse davantage aux règles de conception de services sans état (stateless). Un client accède à la ressource via un URI unique et une représentation de la ressources est ensuite retournée. Avec chaque nouvelle représentation de la ressource, on dit que le client transfère l’état. En accédant aux ressources RESTful avec le protocole HTTP, l’URL de la ressource sert d’identifiant de la ressource et GET, PUT, DELETE, POST et HEAD sont les opérations standard HTTP à appliquer sur cette ressource.

 

REST vs SOAP

Plusieurs facteurs doivent être pris en compte lorsqu’on choisit un type particulier de service Web, soit entre SOAP et REST. Ce qui suit dresse un inventaire des fonctions de chaque service Web, basé selon ma propre expérience personnelle.

REST

  • Les services Web RESTful sont complètement sans état (stateless). Cela peut être testé en redémarrant le serveur et vérifiant si les interactions ont persisté.
  • Les services RESTful proposant une bonne infrastructure de caching via la métthode HTTP GET (sur le plupart des serveurs). Cela peut améliorer les performances si les données retournées par le service Web ne sont pas régulièrement modifées et ne sont pas de nature dynamique.
  • Le producteur et le consommateur du service doivent avoir une même compréhension du contexte et du contenu véhiculé. Il n’existe en effet pas dé règles standard pour décrire une interface de service Web REST.
  • REST est particulièrement utile pour les appareils aux profils restreints, comme les mobiles, pour qui la surcharge de paramètres comme les headers ou d’autres éléments SOAP, est compliquée.
  • Les services REST sont faciles à intégrer aux sites existants et sont exposés en XML. Les pages HTML peuvent les consommer facilement - il est à peine nécessaire de refactoriser l’architecture du site. Cela optimise le productivité des développeurs car ils n’ont pas à ré-écrire du code from scratch, mais à ajouter cela aux fonctions existantes.
  • L’implémentation basée sur REST est simple comparée à SOAP.

SOAP

  • Web Services Description Language (WSDL) décrit les règles communes pour définir les messages, les bindings, les opérations et la localisation du service Web. WSDL est une sorte de contrat formel qui définit l’interface que le service Web offre.
  • SOAP nécessite moins de code que les services REST (par exemple dans les transactions, la sécurité, la coordination, etc…). La plupart des applications ne sont pas simples et reposent sur des opérations complexes, qui nécessitent des états conversationnels et l’information contextuelle pour être maintenues. Avec l’approche SOAP, des développeurs n’ont pas besoin d’écrire ce code dans la couche applicative.
  • Les services Web SOAP (comme JAX-WS) sont utiles pour manipuler les traitements et les invocations asynchrones.
  • SOAP supporte plus protocoles et technologies, tels que WSDL, XSDs et WS-Adressing.

Pour résumer, si vous publiez une API complexe vers l’extérieur, SOAP vous sera plus utile. Mais pour quelque chose avec une courbe d’apprentissage rapide, des transactions simples et des résultats rapides, ma préférence va à REST.

Invoquer un service Web via les procédures stockées de la base Oracle

Consommer un service Web via les procédures stockées d’une base de données permet aux utilisateurs de mettre à jour une base avec des informations issues de sources différentes. Les utilisateurs peuvent également programmer une opération à un rythme régulier pour obtenir les données à jour.

Oracle propose un module « utl_http » pour cela. Vous trouverez ci-dessous un exemple où l’appel au service Web est effectué depuis la base de données.

Les problèmes récurrents lorsqu’on invoque les services Web

Parfois, même après avoir fait correctement effectué la procédure stockée pour appeler le service Web, la procédure ne fonctionne pas. Retrouvez ci-dessous une compilation des erreurs intervenues lors de l’exécution de procédures stockées pour invoquer services Web. Les solutions sont également proposées.

Problème 1 : "ORA-25293 : HTTP request failed" , lors de la compilation de la procédure

Solution: Suivre les étapes ci-dessous pour corriger

      • Se logguer via sys user en tant sysdba
      • Vérifiez les privilèges pour utiliser le package utl_HTTP en entrant les commandes suivantes :
        • select grantee, table_name, privilege
          from dba_tab_privs
          where table_name = 'UTL_HTTP';
      • Le droit sera octroyé à tous les utilisateurs publics par défaut
      • Révoquez le droit sur ut_http et attribuez le explicitement au schema spécifique à partir duquel le service Web doit être invoquer.
        • revoke execute on utl_http from public;
        • grant execute on utl_http to BTFT2;
        • select grantee, table_name, privilege
          from dba_tab_privs
          where table_name =  'UTL_HTTP';

Problème 2: lorsque la procédure stockée qui appelle de service Web renvoie "Network access denied » lors de l’appel

Solution: Ajouter l’URL du service Web à la liste des accès.

      • Se logguer via sys user en tant sysdba
      • Exécuter la procédure suivante pour créer ACL.
        • BEGIN
                DBMS_NETWORK_ACL_ADMIN.CREATE_ACL (
               acl          => '<name of the acl file>.xml',
               description  => 'Permissions to access the web service url',
               principal    => '<Schema name>',
               is_grant    => TRUE,
               privilege    =>
          'connect');
              COMMIT;         
          END;         
          /
      • Créer un rôle puis attribuez connect à ce rôle sur l’ACL via les étapes ci-dessous :
        • créer le role role1;
        • BEGIN

                 DBMS_NETWORK_ACL_ADMIN.ADD_PRIVILEGE (
                                    acl          => '<name of the acl file>.xml',               
                                    principal   => 'role1',
                                    is_grant     => TRUE,
                                    privilege 
             => 'connect',
                                    position     => null);
          COMMIT;
          END;

      • Assignez le nom de l’hôte à l’ACL
        • BEGIN
                DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
               acl          => '<name of the acl file>.xml',               
               host         => '*.<host name of the webservice url>');
          COMMIT;  
          END;  
          /

          Ou

        • BEGIN
                DBMS_NETWORK_ACL_ADMIN.ASSIGN_ACL (
                acl          => '<name of the acl file>.xml',               
                host         => '<ip>’);
          COMMIT;   
          END;
      • Confirmez si le domaine a bien été ajouté à ACL via le package ACL_UTILITY
        • SELECT * FROM
          TABLE
          (DBMS_NETWORK_ACL_UTILITY.DOMAINS('www.ajax.googleapis.com'));
        • select acl , host , lower_port , upper_port from DBA_NETWORK_ACLS;
        • select acl , principal , privilege , is_grant from BA_NETWORK_ACL_PRIVILEGES;

IL existe bien d’autres moyens pour invoquer les services, comme via Jdeveloper ou le package Oracle UTL_DWBS. D’autres options seront également proposées dans les prochaines versions d’Oracle pour la base puisse agir comme à la fois un consommateur et un fournisseur.

Pour approfondir sur Architectures logicielles et SOA