Les URL de Play! étant RESTful par essence, il devient très facile de créer une petite API REST/XML coinjointement à l'interface Web d'une application Play!.
Voyons comment procéder.
Prenons l'exemple d'une bibliothèque musicale. Notre modèle comporte des albums, des artistes et des genres.
La classe Album se présente comme ceci :
@Entity
public class Album extends Model {
public String name;
@ManyToOne(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
public Artist artist;
public Date releaseDate;
@Enumerated(EnumType.STRING)
public Genre genre;
Le genre est une simple Enum, définie comme cela :
public enum Genre {
ROCK, METAL, JAZZ, BLUES, POP, WORLD, HIP_HOP, OTHER
}
Nous voulons définir une URL qui renvoie lors d'un GET la liste des albums au format XML pour un genre donné.
Pour cela nous devons modifier le fichier routes :
GET /website/albums/{genre} Application.list
GET /albums/{genre} Application.listXml(format:'xml')
La première ligne correspond à la page HTML(non présentée dans cet article) affichant la liste des albums disponibles : le format n'étant pas spécifié, le rendu se fera avec une page HTML.
Ici c'est la deuxième ligne qui nous intéresse. Le paramètre (format:'xml') indique que la méthode render() du contrôleur devra chercher un fichier nommé listXml.xml.
Le paramètre {genre} sera récupéré dans l'URL et passé au contrôleur.
NB :
Il est possible d'utiliser une seule méthode dans le contrôleur si les paramètres requis et les traitements sont identiques pour les 2 types de rendus.
Dans notre cas il se peut qu'on ajoute des paramètres à la version HTML ultérieurement, sans vouloir impacter le rendu XML, par exemple :
GET /albums/{genre}/{first}/{count} Application.list
J'ai donc opté pour une séparation du rendu dans deux méthodes distinctes.
Le code de la méthode Application.listXml est le suivant :
public static void listXml(String genre) {
Genre genreEnum = Genre.valueOf(genre.toString().toUpperCase());
List<Album> albums= Album.find("byGenre",genreEnum).fetch();
render(albums);
}
Je recherche simplement les albums correspondant au genre passé en paramètre, et je demande le rendu de la liste. Au passage on voit la simplicité d'utilisation de JPA avec Play!! Le rendu sera fait dans le fichier portant le nom de la méthode et l'extension xml : listXml.xml.
Ce template, placé dans le repertoire app/views, est défini comme ceci :
#{list albums, as:'album'} <album> <artist>${album.artist.name}</artist> <name>${album.name}</name> <release-date>${album.releaseDate.format('yyyy')}</release-date> <genre>${album.genre.toString()}</genre> </album> #{/list}
Voilà, cela suffit pour exposer nos albums en XML. En respectant le pattern d'URL défini dans le fichier routes, par exemple en appelant http://localhost:9000/albums/rock, on obtient le résultat suivant :
<albums>
<album>
<artist>Nirvana</artist>
<name>Nevermind</name>
<release-date>1991</release-date>
<genre>ROCK</genre>
</album>
<album>
<artist>Muse</artist>
<name>Origin of Symmetry</name>
<release-date>2001</release-date>
<genre>ROCK</genre>
</album>
<album>
<artist>Muse</artist>
<name>Black Holes and Revelations</name>
<release-date>2006</release-date>
<genre>ROCK</genre>
</album>
</albums>
Dans le prochain article nous verrons comment envoyer du contenu XML en POST pour ajouter des albums à notre bibliothèque. Lire la suite du tutoriel
9 commentaires:
ah je les vois bien depuis le blog...
mais j'ai l'impression que la librarie js qui affiche le code est de plus en plus longue à se charger (elle est hébergée sur un autre serveur), il faut peut etre attendre quelques secondes...
Quitte à parler des solutions full stack créés par des frenchies, on développe actuellement RESThub (http://bitbucket.org/ilabs/resthub/) qui est très proche de Play! en terme de principes d'architecture (REST et stateless côté serveur, session côté client, pas besoin de redémarrer le serveur), mais en réutilisant les briques existantes comme Maven 3, Spring 3, Tomcat.
RESThub est encore très jeune mais en gros on est aussi efficace que du Play! en terme de rapidité de développement.
La grosse différence entre les 2 c'est que RESThub fournit une stack java + une stack javascript qui réutilisent des briques existantes en ajoutant certains éléments comme des classes génériques, des helpers, etc.
C'est pour ça qu'on le considère comme un toolkit plus qu'un framework, contrairement à Play! qui lui propose ses propres solutions.
Si ça vous intéresse, il y a un thread sur le groupe de discussion des castcodeurs sur les points communs entre les 2 projets : http://groups.google.com/group/lescastcodeurs/browse_thread/thread/c648e16b69c4f7af
Salut Boulaw, je ne connaissais pas RESThub , en effet c'est intéressant je vais regarder ça de plus près!
Vraiment Sympa.
Je ne savais pas que play! pouvait gérer automatiquement les erreurs en format xml je pensais que format:'xml' définissait seulement le type de fichier à rechercher.
Bravo loïc pour ce tuto (je passe à l'autre de ce pas , vive la SNCF et les temps morts...)
Merci Loic d'avoir expliquer comment exposer simplement du contenu XML avec le Framework Play.
Super article. Cependant, étant un grand débutant dans les applications web distribué en xml, j'aimerai savoir si c'était possible de récupérer le code source afin d'avoir un exemple exploitable.
Cordialement,
robertjul
Salut robertjul,
ce code est extrait d'une petite appli qui me sert à construire mes exemples, le code de l'appli est dispo sur google code : http://code.google.com/p/vote4music/
Bonjour,cette article est excellent sur l'extrait du code visant a créer les API.
Enregistrer un commentaire