samedi 31 mars 2012

Un peu de REST

Ce billet est une très brève introduction à la technologie REST et sera complété ultérieurement.

Depuis plusieurs années déjà les WebServices sont à la mode, pour rappel simpliste, un web service est en général une unité de code exposée au monde extérieur. La manière d'utiliser et de communiquer avec cette unité de code est décrite par une enveloppe SOAP (Simple Object Access Protocol). L'enveloppe SOAP décrit un contrat contenant les end-points (ou point d'accès), ainsi que le format des messages pouvant être transférés.

Les web services mettent l'accent sur le process des données, en général on accède à une fonctionalité.

REST (REpresentational State Transfer) donne une autre approche, ici on ne s'intéresse pas aux résultats d'un processing sur les données mais aux données elle même. D'un certain point de vue cette approche est intéressante puisqu'elle rejoins la définition originale des URI

Une URI (Uniform Resource Indentifier) permet d'identifier une ressources

Elle peut être soit une URN (Uniform Resource Name) : ex hello.html ou une URL (Uniform Resource Locator) : http://www.domain.be/hello.html

En général la plupart des URI ne servent pas à identifier ou localiser une resources mais a effectuer des actions:

ex: http://www.sdlg.be/sibyl/updateStudyItem?studyId=123

Ici on désigne clairement une action à effectuer sur une ressource en l'occurrence une study.

En technologie REST l'url aurait plutôt cette forme

http://www.sdlg.be/sibyl/studies/123

Un verbe sera également utilisé : GET, POST, PUT, DELETE.

La représentation des données peut se faire de diverses manières : HTML, XML, JSON

Le framework Spring utilise l'annotation @PathVariable pour récupérer le paramètre 123

De plus pour retourner du json, il faudra modifier le HTTP-HEADER en utilisant un bean de type:

ContentNegotiatingViewResolver et en le paramétrant pour json. Il faudra aussi installer l'artefact:

MappingJacksonHttpMessageConverter pour convertir les objets en flux json.

En PERL, on peut faire cela assez facilement avec JSON::PP (pure perl) ou JSON::XS (compilé en natif) qui contient la fonction to_json qui transforme une map ou une list de map en flux json.

Une rêquete GET en REST pourrait donc renvoyer un flux json représentant l'étude 123.

PUT permettrait de faire juste le contraire renvoyé l'état de l'étude 123 du client vers le serveur.

Avec l'utilisation de plus en plus fréquente de framework javascript basé sur AJAX une approche REST peut avoir quelques avantages non négligeables.

On peut bien sûr aller plus loin, comme SOAP, REST est basé sur HTTP (à la différence de SOAP, il se focalise sur l'état des objets, les données), donc il est possible de créer des clients REST n'ayant rien à voir avec un browser classique.

Il faut aussi noter que REST est nettement moins lourd que SOAP à la mise en oeuvre, maintenant Spring WS fait déjà beaucouop pour nous quant à la mise en place de WebService.


jeudi 29 mars 2012

Cross Tab queries en Oracle 10

Cross-tab queries ou Pivot en Oracle 10g.

Je sais qu'Oracle 11 introduit la notion de Pivot table qui permette de créer des cross tab queris (affichage d'une réponse classée dans un tableau par valeur d'une variable catégorielle). Les adorateurs de SAS connaissent cela via la procedure PROC TABLE qui peut faire un tantinet plus qu'afficher un simple tableau, puisque l'on peut aussi calculer un test de Khi carré mais bon même si mon blog est dédié au stat là n'est pas le sujet du billet d'aujourd'hui.
Par contre les utilisateurs d'Oracle 10 ne peuvent pas bénéficier de cette avancée (bien fait...). Il faut donc trouver un palliatif.
Je prends un cas usuel, nous avons des sujets et ces sujets on différentes propriétés 3 en l'occurrences dans notre exemple. Chaque sujet possède une valeur par propriété. En gros j'ai deux tables, une table sujet et une table propriété.

Une jointure entre les tables nous donne le tableau suivant: V1 et V2 sont des variables numériques, V3 est une variable de type texte.

Sujets
Sujet DOB
1 15/01/2000
2 1/1/1992

Variables
Sujet Nom Valeur
1 V1 15
1 V2 2
1 V3 test
1 V1 17
1 V2 3
1 V3 subj2

La jointure des tables sujets - variables nous donnent ceci

Sujet DOB Nom Valeur
1 15/01/2000 V1 15
1 15/01/2000 V2 2
1 15/01/2000 V3 test
2 1/1/1992 V1 17
2 1/1/1992 V2 3
2 1/1/1992 V3 subj2

Cette approche n'est pas très commode et souffre même d'un certain gigantisme tabulatoire.

Une approche simplificatrice consiste à utiliser une combinaison judicieuse de MAX et de DECODE afin de produire un tableau de type
Sujet V1 V2 V3
1 15 2 test
2 17 3 subj2

Ce que permet le bout de SQL suivant:
select Sujet, MAX(DECODE(Nom, 'V1', VALEUR, NULL)) IV1,
MAX(DECODE(Nom, 'V2', Valeur, NULL)) IV2,
MAX(DECODE(Nom, 'V3', Valeur, NULL)) IV3
FROM Variables
group by Sujet
order by Sujet;

Explication rapide : le DECODE affiche
Select Sujet, DECODE(Nom, 'V1', VALEUR, NULL) IV1,
DECODE(Nom, 'V2', Valeur, NULL) IV2,
DECODE(Nom, 'V3', Valeur, NULL) IV3
FROM Variables

Nous donne un tableau constitué du sujet auquel on concatène chaque valeur de V1, V2, V3. si la variable vaut V1 et qu'elle a une valeur alors sa valeur est affichée, sinon on affiche NULL

Cela nous donne

Sujet V1 V2 V3
1 15 null null
1 null 2 null
1 null null test
2 17 null null
2 null 3 null
2 null null subj2

On remarque que par sujet on obtient une matrice diagonale. L'utilisation d'un regroupement sur MAX permet d'éliminer les valeurs nulles.

Vous remarquerez qu'Oracle a une drôle d'interprétation de la nullité. Nous savons en effet que null signifie que l'on ne connaît pas la valeur. Si Alain à un age de 30 ans et Philippe un age inconnu que vaut le MAX(Age) entre Alain et Philippe. La réponse est normalement je ne sais pas. Pour Oracle la réponse est Alain. C'est assez divinatoire (sans mauvais jeu de mot) comme approche mais ça marche pour notre exemple, nous ne nous en plaindrons donc pas !

dimanche 25 mars 2012

Maven 2

Maven 2

est équivallent à la procédure de build management (produire un logiciel à partir de ses sources en automatisant certaines tâches)
Il gère aussi les dépendances (external jar).

Nomenklatura
artefact: élément spécifique de la construction du projet (en général des jar) mais ça peut -être des war, des ear, ...
dépendance: c'est une dépendance du projet vers un artefact
snapshot : version du projet en cours de développement.
POM : Project Object Model : paradigme qui décrit le projet logiciel, ses dépendances et l'ordre des tâches à effectuer pour le produire. Basé sur XML (pom.xml) mais un peu plus simple qu'ANT.

Ils fonctionnent en réseau, peut télécharger des jar venant de répository connus et gère aussi les dépendances récursives.

Le fichier POM.xml contient les propriétés du projet parent, il est possible de redéfinir ces propriétés (héritage).

Convention de répertoire MAVEN
/src
/src/main
/src/main/java
/src/main/resources (images, fichiers, annexe, ...)
/src/main/webapp

/src/test
/src/test/java
/src/test/resources

/src/site : information relative au projet généré
/src/target : executables, jar, ...

Cycle de vie

compile
test
package (crée le jar dans target)
install
deploy

Ces opérations sont des opérations basiques de building, et fonctionnent sous forme de plugins que l'on peut ajouter dans le project object model. On est donc pas figé à ces seules étapes du cycle de vie.

Limitations
Certains artefacts ont des license agreement et ne sont donc pas directement résolvable par maven.
Ex: javax.naming.jndi

Référence
http://java.developpez.com/faq/maven/?page=terminologie