"…mais ce serait peut-être l'une des plus grandes opportunités manquées de notre époque si le logiciel libre ne libérait rien d'autre que du code…"

Archive for the ‘REST’ Category

Des nouvelles de python: Sun supporte Jython et Python, Django, Mailman3 (MM3, REST), Barry Warsaw reçoit le prix Pizzigati pour GNU/Mailman

Posted by patrick sur mars 6, 2008

Jython et Sun

http://ironpython-urls.blogspot.com/2008/03/ironpython-has-serious-competition-sun.html (« In September 2006 Sun hired two JRuby developers to improve the story of dynamic languages on the JVM. This was seen by many as both long overdue and a response to Microsoft developing IronPython (and the Dynamic Language Runtime) for .NET. As Jython has been around for longer than JRuby, many in the Python community wondered why Sun weren’t supporting Python. Finally they have answered, by hiring Ted Leung and Jython lead developer Frank Wierzbicki.« )

http://www.sauria.com/blog/2008/03/03/the-sun-is-going-to-shine-on-python/ (…Over the years, I’ve met many people at Sun who understand a collaborative development style. Many of those folks are committers on Apache projects…How serious is Sun about dynamic languages and how deep does that support go? Sun is (finally?) very serious about this. As part of Sun’s new direction, Sun wants to give developers the ability to use whatever tool sets they want. Ruby, Python, PHP, Java. On or off OpenSolaris. On or off the JVM. There is an official project, John Rose’s DaVinci Machine Frank Wierzbicki, the maintainer of Jython, started at Sun last Monday, so there will be at least two of us working on Python related stuff. That includes Jython, Python support for Netbeans, and some other stuff that we haven’t quite figured out yet. We definitely will be looking for things that we can do to support CPython and the Python language as a whole. This is not just about Python on on the JVM. Sun will try to make its platforms, OpenSolaris and the JVM, the best place to develop and deploy Python applications. But at the moment that’s a goal and not a reality, so there is lots to do. )

http://fwierzbicki.blogspot.com/2008/02/jythons-future-looking-sunny.html (« …So by now you’ve probably guessed it: Sun Microsystems has hired me to work full time on Jython. They have also hired Ted Leung to represent the wider world of Python at Sun. I don’t think I can overstate just how excited I am about this. For a long time now I’ve been obsessed with Jython. Now I will be able to let my obsession take over completely…I have to especially thank Tim Bray, who has been pushing the dynamic language thing at Sun for quite a long time. I’m sure the warm welcome that I got at Sun was in no small part due to the enormous success of the JRuby work that has been going on there, so thanks to Charles Nutter and Thomas Enebo for their work. Also thanks to the many folks at Sun who have been pushing for this, including Eduardo Pelegri-Llopart. And of course thanks to all of you who use, contribute to, and talk about Jython. Jython is above all things a community effort. We should all share in the excitement. Hurray!« )

http://www.tbray.org/ongoing/When/200x/2008/03/03/Python-at-Sun (« So, as of this morning, noted Pythonista Ted Leung and Jython lead Frank Wierzbicki are joining Sun. Plus, we’re sponsoring PyCon and have applied to join the Python Software Foundation (it turns out you not only have to contribute, you have to get voted in). So, what are these guys going to be working on? I’m not sure. While we’re using Python internally for OpenSolaris IPS, nobody would call us real experts on the language. So my opinion is that Frank and Ted need build bridges to the community and figure out how we can help; if we can pitch in as well with Python as we have with Ruby, that’d be a win/win I’d say. Quick Python trivia question: Near as I can tell, Guido works half-time on Python over at Google. Is there anyone in the world, aside from Frank and Ted, getting paid to work full-time on Python ?« )

Django

  • http://www.jacobian.org/writing/2008/feb/21/sailing-on/ (« …However, I’ve been offered every Open Source developer’s dream job. Starting in March, I’ll be spending the majority of my time working on Django….So what exactly will I be doing? My job will entail a bit of internal-only closed-source development, but nearly everything I write will be Open Source. Most of my time will be spent improving Django. In the short term that’ll mean fixing tickets, working on new features, getting active branches finished and merged to trunk, and getting a one-point-omg release out the doorLast year I spent a few days in Boulder helping the Front Range Pythoneers kick off the Oracle backend for Django. It was a huge amount of fun, and I’m going to make myself available to other groups wanting to working on other similar problemsI can’t wait to spend my days hacking on Django. The best part is that this isn’t the only piece of good news about Django I’ll get to share this year. Stay tuned: 2008 is going to be huge« )

Mailman 3

  • http://wiki.list.org/display/DEV/REST+Interface (« I’m interested in working on a REST-style interface for controlling Mailman. One thought: should the web UI be written atop such a REST interface? Pro: it would nicely enforce decoupling the UI and the Mailman engine, and be a good test that the REST interface supports enough functionality. Con: adds an extra layer…I’m really keen on exploring this because I do think the decoupling will be a big win. It’ll let us distribute a turnkey, standalone u/i for those who want something working out of the box, but it’ll also let integrators use the core Mailman engine in their own sites. And it won’t limit you to just Python web frameworks (A sketch of the REST interface is in the wiki at http://wiki.list.org/display/DEV/REST+Interface . It’s written from the 2.1/2.2 point of view; I don’t know if mm3 reworks the basic objects so much that the REST interface no longer applies.). This interface isn’t intended to be exposed to the Internet at large, so there’s no mention of access control. It would be used as a back-end, on top of which the existing Mailman interface, or a fancy GUI application, or administrative scripts, could be built
    I think if we’re careful we can get pretty close. Ideally, we’d have
    the same REST api for both, which would give us a nice migration path, but I don’t yet know if that’s feasible. MM3 does have a more elaborate data model than MM2, but OTOH, everything is formally declared in Zope-style interfaces (and thoroughly tested… woohoo!). One thing that we have to figure out is how to represent all the metadata that currently lives in the Mailman.Gui package of 2.1/2.2. I think any web interface acting through the REST api will want that basic information, e.g. the brief and detailed descriptions of the mailing attributes (the VARHELP). I’m sure there’s a clear way to publish that through the REST api, but it might have an impact on the format used. I like JSON a lot, but html or xml might be more amenable to that type of data. OTOH, it’s all read-only so it might make sense to split it into two trees of information.
    « )

Mailman

  • http://mail.python.org/mailman/listinfo/mailman-announce(« 
    I realize that I’ve been remiss in announcing this. My apologies. I have been awarded the 2008 Pizzigati Prize for Public Interest
    Computing for GNU Mailman. http://www.pizzigatiprize.org/
    I am deeply honored to win this prize because I believe very strongly
    in Mailman’s role in helping people communicate and organize. I want
    to thank all of you who have supported me and Mailman over the years, and I want to let you know that I am as excited as ever about where Mailman is going. One of the most satisfying aspects of this project for me has been meeting you, the users, developers and contributors to Mailman, both online and face-to-face. I’m looking forward to meeting the Pizzigati family and having some time to spend with them learning about Anthony’s remarkable life, sadly cut too short. So again, thank you all and I’m looking forward to the next 10 years of GNU Mailman!Cheers,
    – -Barry »)
  • http://www.pizzigatiprize.org/news/press_releases/barry_warsaw_named_second_annual_winner_of_the_10,000_pizzigati_prize.html (« San Francisco, January 30, 2008— Tides Foundation announces the winner of the second annual $10,000 Pizzigati Prize. Barry Warsaw, a software developer dedicated to identifying and solving the technological problems that confront social change movements, has won the Antonio Pizzigati Prize for Software in the Public Interest.
    Barry Warsaw is being recognized for his work as the lead developer of GNU Mailman, the open source application that hundreds of nonprofits around the world are now using to manage electronic mail discussions and e-newsletter lists. The Pizzigati Prize — an award program launched two years ago by Tides Foundation’s Florence and Frances Family Fund — aims to honor individuals who, in the spirit of open source computing, fashion outstanding applications that help nonprofits become more effective in their ongoing social change efforts. “Barry Warsaw has displayed, over the years, a powerful personal commitment to the ideals behind the Pizzigati Prize,” notes Jason Sanders, Tides Philanthropic Advisor who coordinates the prize competition. “His work has demonstrated vision and inspired innovation in public interest computing
    .« )
Publicités

Posted in jython, logiciel libre, python, REST, Web Frameworks | Tagué: , , , | 2 Comments »

Compte rendu de la conférence Ruby/Ruby On Rails du mercredi 19 décembre 2007 à Grenoble

Posted by patrick sur janvier 7, 2008

Bonjour et bonne année 2008 (1) mais aussi 5768, 1428, 1386, 4405, etc. 🙂

C’est avec plaisir que j’ai assisté à la conférence sur Ruby et Ruby On Rails. Etant un fan du langage Python, j’apprécie à sa juste valeur le langage Ruby et son framework Web bien connu Ruby On Rails. Cela fait plaisir de voir que je ne suis pas le seul à apprécier ce genre d’environnement (avec Python il y a Django, Grok, Pylons) et qu’il est bien regrettable que les entreprises ne pensent qu’à l’artillerie lourde JEE même pour des applications petites ou moyennes.

La conférence s’est déroulée en 2 parties. D’abord une présentation de Ruby et ensuite une présentation de Ruby On Rails.

Ici, le support de la conférence: http://www.guilde.asso.fr/rencontres/20071219/Ruby_Rails_Introduction_PoR_2007_longue_v2.pdf
Ce que j’ai appris:

– le modèle objet de Ruby est fortement inspiré de Smalltalk

– Ruby applique le principe POLS ( principle of least surprise)

– les blocs sont employés partout dans Ruby

– il n’y a pas d’héritage multiple mais on peut utiliser des mixins (étend les compétences d’une classe en lui rajoutant une série de méthodes)

– les conventions de nommage sont importantes

– il y a un haut niveau de métaprogrammation

– Ruby est bien adapté pour implémenter des langages spécifiques (DSL)

– pour les grosses applications il faut utiliser n instances de mongrel derrière un serveur Apache faisant office de répartisseur de charge. (« One popular configuration is to run Apache 2.2 as a load balancer using mod_proxy_balancer in conjunction with several Mongrel instances, with each Mongrel instance running on a separate port. This is something that can be configured very easily using the mongrel_cluster management utility. Apache can divide the incoming requests among the available Mongrel processes, and, with careful configuration can even serve static content itself without having to delegate to Mongrel. »)

– Sun s’intéresse fortement à Ruby ce qui explique que de plus en plus de développeurs Java s’intéressent à Ruby. La version 6 de Netbeans intègre Ruby et Ruby On Rails (« Since version 6.0, Netbeans allow IDE development with Ruby and JRuby, as well as Rails for these two implementations of Ruby…It is also possible to create directly Ruby projects or Ruby on Rails projects, using the reference Ruby implementation, or using JRuby (the Java implementation of Ruby) . »)
Sites à voir:

http://www.rubyfrance.org/ (« Site de l’association francophone des utilisateurs du langage de programmation Ruby« )

http://www.railsfrance.org/ (« Rails est un framework, basé sur le langage Ruby, permettant le développement rapide d’applications web utilisants le modèle MVC (Modèle-Vue-Contrôleur). »)

Laurent Julliardhttp://paris.onrails.info/conferenciers (« Laurent Julliard est un fervent utilisateur du langage Ruby depuis 2000. Traducteur de l’ouvrage « Agile Web development with Rails » pour Eyrolles, il a en outre participé a plusieurs projets Ruby dont l’environnement de développement FreeRIDE. Il s’est investi de longue date dans le mouvement Open Source en créant le premier groupe d’utilisateur Linux français en Janvier 1995 (La GUILDE). Après avoir occupé des postes de leader techniques et d’architecte logiciel dans les laboratoires de R&D de Hewlett-Packard et de Xerox en France et aux Etats-Unis, il est aujourd’hui Directeur Associé de Nuxos Group. »)

http://www.journaldunet.com/developpeur/outils/interview/07/1210-paris-on-rails.shtml (« Quels sont les points forts du framework Ruby on Rails ? Après 10 ans de développement d’applications Web avec des logiques métier fortes, on s’est retrouvé avec une véritable cacophonie au niveau des frameworks, les composants partant un peu dans tous les sens. Face à cette problématique, Rails propose un cadre reposant sur le modèle MVC, Modèle Vue Contrôleur. L’idée était d’appliquer ce modèle de développement qui a fait ses preuves à l’univers de la programmation Web... Ecrit en Ruby, Rails a donc proposé de couvrir ces trois couches. D’où sa qualification de full-stack application framework. C’est d’ailleurs pour cette raison que David Heinemeier Hansson, le créateur du framework, a indiqué qu’il n’avait rien inventé de nouveau. Ruby on Rails agrège des bonnes pratiques en les intégrant à un outil de façon cohérente…

…Sun sponsorise la conférence Paris on Rails cette année. Comment cet acteur se situe-t-il vis-à-vis du projet ? Le buzz généré par Rails a entraîné l’apparition de clones, notamment PHP (CakePHP, Symphony) et Python (Django, TurboGears, Pylons). Des développeurs ont également travaillé au portage de Ruby sur la machine virtuelle Java. Il s’agit de Charles Oliver Nutter et Thomas Enebo. C’est le projet JRuby. Conscient des potentialités de Rails et des limites de ses propres outils de développement, Sun a décidé de les embaucher. C’est très intéressant, dans la mesure où avec JRuby il devient possible de reprendre des classes Java dans une application Ruby via Rails. Plusieurs grandes entreprises s’intéressent déjà à cette initiative, notamment des banques du Luxembourg. Sun a déjà étendu NetBeans en y ajoutant des greffons pour Ruby on Rails. On note une initiative équivalente chez Microsoft qui a pour but de porter Ruby sur l’infrastructure .Net et la CLR (IronRuby, voir Ironpython). Même démarche du côté d’Apple qui supporte Ruby on Rails dans le système Leopard lorsqu’on installe son kit de développement

…Quel est aujourd’hui le public de Paris on Rails ? Parmi les inscrits, on compte à la fois des start-up qui privilégient des environnements de développement rapide, mais également des grandes entreprises qui s’intéressent de plus en plus à Rails, notamment au travers de cellules de veille et de projets de prototypage. Beaucoup de sites Web reposent sur Rails. C’est le cas du site de vidéos Eyeka, des sites du Figaro Madame et de la partie shopping du Nouvel Obs. Au niveau des grandes entreprises, la banque RBC Dexia a récemment adopté Ruby on Rails. Cette société a réalisé le déploiement d’une vingtaine d’applications depuis le mois de septembre dernier. Un rythme de livraison jamais atteint au sein de cette banque. Il est clair que l’arrivée de JRuby (voir Jython) est très intéressant pour les structures d’une certaine taille. Il permet en effet d’adopter Rails tout en étant capable de reprendre l’existant Java, et de s’y intégrer. Le changement peut ainsi s’effectuer en douceur…Qu’en est-il des développeurs Rails en France ? Ils sont toujours très peu nombreux comparé aux pays voisins où la communauté est plus importante. De ce fait, le coût des profils de développeur Rails est très élevé chez nous. C’est clairement un facteur bloquant l’extension de Rails en France. Nous organisons Paris on Rails notamment dans l’objectif de sensibiliser les développeurs à la technologie Rails et à ses potentialités. Historiquement, les développeurs Web français se sont beaucoup focalisés sur PHP pour les applications Web. Nous voulons les pousser à sortir des sentiers battus« )

http://en.wikipedia.org/wiki/Ruby_%28programming_language%29 (« The language was created by Yukihiro « Matz » Matsumoto, who started working on Ruby on February 24, 1993, and released it to the public in 1995. « Ruby » was named as a gemstone because of a joke within Matsumoto’s circle of friends alluding to Perl’s name. As of March 2007, the latest stable version is 1.8.6. Ruby 1.9 (with some major changes) is also in development. Poor performance of the current Ruby implementation in comparison to other more entrenched programming languages has led to the development of several virtual machines for Ruby. These include JRuby, a port of Ruby to the Java platform, IronRuby, an implementation for the .NET Framework produced by Microsoft, and Rubinius, an interpreter modeled after self-hosting Smalltalk virtual machines. The main developers have thrown their weight behind the virtual machine provided by the YARV project, which was merged into the Ruby source tree on 31 December 2006, and will be released as Ruby 2.0. »)

Dernières nouvelles:

http://www.rubyfrance.org/articles/2007/12/25/sortie-de-ruby-1-9-0/ (« Ruby 1.9.0 est disponible ! Joyeux Noël ! Ruby 1.9.0 est la première version publique de Ruby comportant une machine virtuelle, ainsi que le nouveau moteur d’expression rationnelles Oniguruma, la gestion de m17n (multilingualization, notamment une meilleure gestion d’Unicode), les fibres, une présence accrue des énumérateurs (enumerator), des nouvelles constructions syntaxiques (->() {} etc.) RubyGems 1.0.1 (sorti la semaine dernière) et Rake 0.8.0 sont désormais intégrés à Ruby, FasterCSV remplace CSV. Matz n’a pas voulu nommer cette version 1.9.1 comme initialement prévue, car certains tests ne passaient pas, cette version n’était pas assez stable à son goût. En passant, notons que Perl, langage qui a influencé le design de Ruby, fête ses 20 ans, avec la mise à disposition de Perl 5.10″)

http://www.programmez.com/actualites.php?id_actu=2608 (« Depuis le 6 décembre 2007, la version 2.0 du désormais célèbre Ruby on Rails, est disponible en version finale ! Attendue depuis plusieurs mois, cette version consolide les fonctions et les acquis des versions 1.x. Un important travail a été réalisé sur les ressources, notamment dans tout ce qui est RESTful. Dans le multivue, Rails 2 sépare le format du template du moteur de rendu. Ainsi, on peut donner à son application une interface iPhone… Des améliorations concernent aussi le support de HTML, la sécurité (par exemple : gérer une attaque XSS), la gestion des exceptions mise à niveau, l’apparition d’un nouveau stockage des sessions par un mécanisme de cookies (la session n’est plus gérée dans une base). Un gros travail a été réalisé sur Active Record pour l’alléger et l’optimiser, ainsi la désérialisation XML est supportée. Rails 2 réintroduit le debugger (installable via un simple gem, le format d’installation de Rails). Pour toute migration, il faut d’abord installer la version 1.2.6 avant de passer à la 2.0. Quant à la sortie de la 2.0 de Ruby, rien n’est encore fixé. Une première version devrait apparaître vers la mi-2008. »)

http://linuxfr.org/2007/12/11/23448.html (« Ruby on Rails, le célèbre framework basé sur le langage Ruby, permettant le développement rapide d’applications web selon le modèle MVC (Modèle, Vue, Contrôleur) sort en version 2.0. Le développement qui a duré une année a permis l’ajout de nombreuses fonctionnalités, la résolution de beaucoup de bugs, une orientation tournée vers le REST, et pas mal d’allégements au niveau du core (externalisation de fonctionnalités en greffons)…

Ressources et webservices Rails a tranché dans le débat REST – SOAP au profit du REST. Le module ActionWebservice a été sorti du core et placé en greffon pour ceux qui veulent continuer à utiliser du SOAP. ActiveResource est le nouveau module qui est similaire à ActiveRecord mais avec une approche ressource. Au passage, l’url des ressources a été modifié, l’utilisation du point virgule ( ; ) pour séparer l’action de la ressource a été remplacé par un slash ( / ), à cause de navigateurs et bibliothèques HTTP qui ne le supportaient pas en tant que séparateur de requêtes...Multi-vues Rails 2.0 sépare le format du template (html, xml, atom, rss, …) du moteur de rendu. Le template show.rhtml devient donc show.html.erb (ERB étant le moteur de rendu par défaut).
D’autres moteurs de rendus existent aussi, builder utilisé pour générer du atom+xml, et HAML principalement utilisé aujourd’hui pour générer des templates adapté à l’iPhone.
..Session basée sur les cookies
Les sessions ne sont plus stockées par défaut sur le système de fichiers du serveur web mais au niveau du client sous une forme qui ne peut pas être forgée. En revanche, le contenu sera visible, donc ce mécanisme de stockage de sessions n’est pas adapté si vous avez besoin d’y stocker une information que ne doit pas voir l’utilisateur.
« )

(1) http://fr.wikipedia.org/wiki/2008 (« L’année 2008 du calendrier grégorien correspondra aux années suivantes :

Posted in 2007, active record, machines virtuelles, ORM, REST, ruby, Web Frameworks | Tagué: , , , , | Leave a Comment »

Les dernières nouvelles du monde DotNet : ADO.NET Data services, LINQ, Mono 1.2.6, Visual studio 2008, silverlight2.0

Posted by patrick sur décembre 13, 2007

En vrac:

ADO.NET Data Services (Astoria Project)

  • http://astoria.mslivelabs.com/ (« The new wave of web applications are built on technologies such as AJAX and Microsoft Silverlight that enable developers to build better, richer user experiences. These technologies bring a shift in how applications are organized, including a stronger separation of presentation from data. ADO.NET Data Services (also known as Project code name “Astoria”) consists of a combination of patterns and libraries that enables any data store to be exposed as a flexible data service, naturally integrating with the Web, that can be consumed by Web clients within a corporate network or across the Internet. ADO.NET Data Services uses URIs to point to pieces of data and simple, well-known formats to represent that data, such as JSON and ATOM/APP. This results in data being exposed to Web clients as a REST-style resource collection, addressable with URIs that agents can interact with using standard HTTP verbs such as GET, POST, or DELETE. » Je rajoute un bémol à la dernière phrase qui est inexacte: DELETE n’est pas un verbe HTTP. Pour rappel voir le billet que j’avais écrit à propos de Django: The method of an HTML form is limited to GET and POST. PUT and DELETE are not allowed. This isn’t some failure of browser vendors to properly implement the specification either. The HTML specification only allows GET and POST as form actions. XHTML and even XForms 1.0 don’t change this. This means it’s impossible to build a fully RESTful client application inside a web browser. Consequently everyone tunnels everything through POST, and simply ignores PUT and DELETE)

LINQ

  • http://tirania.org/blog/archive/2007/Oct-24.html (« OpenSource LINQ providers: The Db_Linq is an open source project to create a LINQ provider for other databases. The project is lead by George Moudry and so far has providers for PostgreSQL, Oracle and Mysql. George keeps a blog http://code2code.net/wordpress/ where you can track the development of DbLinq. Thanks to Bryan for pointing me out to this fantastic piece of code. Mono users on Linux will now be able to use LINQ with open source databases from C# (in addition to our in-memory and XML providers). Update: A nice blog entry talks about Parallel LINQ. A version of LINQ that can be used to parallelize operations across multiple CPUs:

    IEnumerable data = …;

    // Regular code:
    var q = data.Where(x => p(x)).
    Orderby(x => k(x)).Select(x => f(x));
    foreach (var e in q) a(e);

    // Parallelized version, add the « AsParallel » method:
    var q = data.AsParallel().Where(x => p(x)).
    Orderby(x => k(x)).Select(x => f(x))

    See more details about the above in the Running Queries On Multi-Core Processors article.« )

  • http://spellcoder.com/blogs/bashmohandes/archive/2007/10/14/8530.aspx (« I’ve been hearing about PLINQ (Parallel Linq) since the first days of announcing LINQ, the idea of making use of the new functional style programming provided in DotNet 3.5 in order to give better performance on Multi Core machines, the idea sounds cool since first day, and it now comes true in a new name Parallel FX or PFX. The programming model provided is quite simple and utilizes the same LINQ model, the new assembly is called System.Concurrency.dll which is the library that contains the new interface called IParallelEnumerable<T>, also it adds an extension methods for all collections and arrays that implement old IEnumerable, the extension method is called AsParrallel<T> which converts any collection to a Parallel enabled collection of type IParallelEnumerable<T> »)
  • http://en.wikipedia.org/wiki/Language_Integrated_Query (« Language Integrated Query (LINQ, pronounced « link ») is a Microsoft .NET Framework component that adds native data querying capabilities to .NET languages using a syntax reminiscent of SQL. Many of the concepts that LINQ has introduced were originally trialled in Microsoft’s research project. LINQ has been released as a part of of .NET Framework 3.5 on November 19, 2007. »)

Visual Studio 2008

Mono

  • http://www.mono-project.com/news/archive/2007/Dec-12.html (« We have just released Mono 1.2.6. Some of the highlights for this release include:
    • Native Windows.Forms driver for MacOS X allows Winforms-based applications to run without an X server.
    • Support for the ASP.NET AJAX APIs and controls.
    • Support for FastCGI deployments: ASP.NET can now be deployed on a multitude of servers that implement the FastCGI protocol (lighttpd for example) in addition to Apache.
    • Windows.Forms now supports the WebControl on Windows and Linux using Mozilla.
    • Runtime will now consume much less memory for 2.0-based applications due to various optimizations in generics support as well as including many new performance improvements and an updated verifier and an implementation of CoreCLR security.
    • C# compiler is quickly approaching full 3.0 support, most of the basics work right now (except support for System.Query.Expression AST generation).
    • Mono 1.2.6 can now be used as an SDK for creating Silverlight 1.1 applications on all platforms. This allows developers to create applications that target Silverlight without requiring a Windows installation.« )

silverlight

ironpython

  •  http://ironpython-urls.blogspot.com/2007/12/ironpython-studio-now-available.html ( » IronPython Studio is a free full IDE (Integrated Development Environment) for the Python programming language. It is based on the existing IronPython example that is included in the VS SDK. IronPython Studio is based on the Visual Studio 2008 Shell runtime (royalty free) and can be installed without requiring any version of Visual Studio. It is hosted on codeplex. Installer, source and screencast are available from the download page. The sources require Visual Studio 2008 (Team Edition apparently) and the SDK. NOTE: Some users (myself included) had trouble getting this working. The magic steps are:
    • Download and install the Visual Studio X redistributable from: Visual Studio Extensibility
    • After you run the Install for the MS VS 2008 Shell Isolated Mode Redistributable, you must then go to the folder (« C:\VS 2008 Shell Redist\Isolated Mode« ) and click on: « vsshellisolated_enu.exe » to actually install the redistributable runtime.
    • Install IronPython Studio. Thanks to Tom Clark for the instructions. »)

Posted in Acces aux données, AJAX, Développement logiciel, multi-core, python, REST, RIA | Tagué: , , , , , , , , , , | Leave a Comment »

Des nouvelles du monde python: ironpython, windmill, satchmo, grok + le réseau social ohloh.net

Posted by patrick sur novembre 10, 2007

Quelques nouvelles du monde python:

  • différentes mesures de la popularité du langage python sur http://www.langpop.com/. Le langage C vient en première position tandis que Python se situe entre la 6e et la 12e position suivant les outils de mesure.
  • la version 2.06a de Ironpython est sortie (« …this release includes all of the changes we have made in the past month. The most noteworthy differences include:
    • the IronPython project is now distributed under the Microsoft Public License (Ms-PL)
    • improved support of COM events under the –X:PreferComDispatch flag
    • the abstract syntax tree for IronPython is being hardened so to speak
    • we have included an updated DLR sample in the source zip file – ToyScript
    • Internally we have migrated our Visual Studio project and solution files over to a Visual Studio 2008 beta release. While we’ve modified these files in the source distribution of IronPython to be compatible with Visual Studio 2005 and the msbuild tool, it’s possible we may have missed something. If you experience any problems building IronPython from VS tools please let us know.
    • The ToyScript sample is not intended to be distributed with IronPython on a permanent basis and will likely be released in some other fashion in the not too distant future. »)
    • For whatever reasons, IronPython 2.0 Alpha 6 started to invoke delegate to abstract method. (Previous versions didn’t.) This triggered Mono bug 317488 which is apparently hard to fix. https://bugzilla.novell.com/show_bug.cgi?id=317488 I developed completely insane workarounds to avoid this problem. Now you can laugh (or weep). https://fepy.svn.sourceforge.net/svnroot/fepy/trunk/patches/latest/patch-317488
  • Source: http://www.voidspace.org.uk/python/weblog/ (« ...Web application testing with Windmill. A new (Python based) browser testing tool was just announced on the Testing in Python Mailing List. It comes out of the Chandler Project and claims to implement a larger set of a browser testability than Selenium: Windmill.
    • Windmill is an Open Source AJAX Web UI Testing framework written in Python and JavaScript originally for testing the Chandler Server WebInterface at OSAF. After spending time with Selenium we realized we had a variety of needs that weren’t being fulfilled and built Windmill from the ground up. Windmill implements cross browser testing, in-browser recording and playback, and functionality for fast accurate debugging and test environment integration. Support for Firefox, IE6/7, Safari on * *Windows, Linux and Mac OS 10.4 and 10.5.)
  • http://www.ohloh.net/projects/search?page=1&q=django (« Ohloh is an open source network that connects people through the software they create and use. Ici on recense les projets basés sur le framework web python Django. »)
  • http://www.satchmoproject.com/ (« ...Satchmo’s mission is to use Django to create an open source framework for creating unique and robust online stores. To provide maximum flexibility, Satchmo is licensed under the BSD license…. This project was started by a group of individuals that were interested in using the Django framework to create a robust shopping cart solution. After some more discussions, we have decided to focus on building a modular framework of shopping cart or eCommerce packages that can be easily put together to form a full store. Here’s a bunch of questions you might be asking yourself at this point… Why use Django? First off, we wanted to use Python for the project. Many of us have experience with similar PHP based projects and we quickly realized that they tend to break down pretty quickly under the unwieldy syntax, lack of good OO support and hackish nature of many of the projects. Once we decided on Python, there were many frameworks to evaluate. They all have tradeoffs but there are some things we really liked about Django:
    • Robust, scalable system that has been used on major commercial sites
    • Clean separation of program logic from presentation
    • Nice abstraction of SQL (but with the capability to code SQL if required)
    • Solid documentation
    • URL mapping capabilities will be very useful for a shopping cart solution
    • Out of the box admin capabilities making it easy to get up and running & provide enhanced security for multiple users in a store.

This list is not exhaustive and there could be endless debate and flamewars on the choices but we’ve all reached this decision independently and encourage you to investigate & make your own choice….« )

  • http://grok.zope.org/ (« Grok is a web application framework for Python developers. It is aimed at both beginners and very experienced web developers. Grok has an emphasis on agile development. Grok is easy and powerful. You will likely have heard about many different web frameworks for Python as well as other languages. Why should you consider Grok?
    • Grok offers a lot of building blocks for your web application.
    • Grok is informed by a lot of hard-earned wisdom.

Grok accomplishes this by being based on Zope 3, an advanced object-oriented web framework. While Grok is based on Zope 3, and benefits a lot from it, you do not need to know Zope at all in order to get productive with Grok« )

..etc, etc…

Posted in Ironpython, python, REST, tests, Web applications | Tagué: , , , , | Leave a Comment »

OpenSocial : les APIs « sociales » open source de Google

Posted by patrick sur novembre 3, 2007

L’article que j’ai écrit le 30 octobre mérite d’être complété. Google qui était en retrait des réseaux sociaux (Orkut) fait une entrée fracassante avec son API « OpenSocial ».

Source: http://fr.techcrunch.com/2007/10/31/google-lance-jeudi-opensocial-premiers-details/
Rédigé par Ouriel Ohayon

Google avait annoncé un plan important concernant sa stratégie de réseau social qui devait être annoncé le 5 novembre. Nous avons révélé de plus amples détails récemment sur ce projet au nom de code “Maka-Maka”. Mais il semble que la réalité va bien au dela de nos attentes. Le projet de Google portera le nom de OpenSocial et ne sera pas un méta-réseau social comme on aurait pu l’imaginer. Il s’agit en fait d’une séries d’API qui permettent à des développeurs de créer des applications compatibles avec toutes les plateformes sociales qui désirent participer au programme.

Il ne s’agit donc pas d’une n-ième plateforme sociale. L’autre avantage est que ces APIs ne vont pas nécessiter d’apprendre, contrairement à Facebook, un nouveau langage (FBML) et un développeur n’aura plus à choisir la plateforme sociale pour laquelle il doit développer son application. Il pourra même utiliser ses codes existants en Javascript et Html et légèrement les modifier pour mettre cela en place. Il y a 3 types d’API:

  • Celles pour le profil utilisateur,
  • celles pour le réseau social
  • et celles pour le flux d’activités (news feed)

Si un site accepte de participer, il devra retourner les données appropriées en utilisant ces APIs.Il n’y a pas de précisions concernant certains points clefs comme par exemple la possibilité d’inclure de la publicité ou le mode d’inscription pour user de ces APIs.

Pour son lancement Google annoncera plusieurs partenaires partagés en “hôte” et “développeurs”. Les Hotes sont ceux qui hébergeent les applications et les développeurs ceux qui les développent. Orkut, Salesforce, LinkedIn, Ning, Hi5, Plaxo, Friendster, Viadeo et Oracle seront les premiers hotes et Flixster, iLike, RockYou et Slide seront les premiers développeurs. Zlio sera la première startup française également partenaire du programme mise à jour: Viadéo serait le second acteur français à faire partie de ce programme

Comme je l’avais signalé dans ce billet, avec la prolifération des plateformes sociales, un développeur doit faire face à un dilemme quand il s’agit de créer son application et doit soit choisir sa plateforme soit multiplier les efforts pour être présent sur les principales plateformes. Google souhaite rendre ce dilemme caduque et va faciliter la vie des développeurs.

Autres sources:

  • http://code.google.com/apis/opensocial/ ( » The web is more interesting when you can build apps that easily interact with your friends and colleagues. But with the trend towards more social applications also comes a growing list of site-specific APIs that developers must learn. OpenSocial provides a common set of APIs for social applications across multiple websites. With standard JavaScript and HTML, developers can create apps that access a social network’s friends and update feeds. »)
  • La vidéo: http://www.youtube.com/GoogleDevelopers
  • http://actu.abondance.com/2007/10/opensocial-des-apis-sociales-en-open.html (« Le projet, qui avait au départ reçu le nom de code « Maka-Maka » (ou « MakaMaka ») chez Google, devrait être dévoilé au grand jour demain 1er novembre sous le nom d’OpenSocial : il s’agit d’API (Application Program Interface ou bibliothèques de fonctions pour programmeurs) qui permettra aux développeurs informatiques de créer des applications compatibles avec les réseaux sociaux existants ou tout du moins ceux qui désirent être associés à ce programme. Trois types d’APIs devraient être proposés : profil utilisateur, réseau social lui-même et flux (news feed). Parmi les premiers réseaux pressentis pour participer à ce programme, on trouverait Orkut, Salesforce, LinkedIn, Ning, Hi5, Plaxo, Friendster, Viadeo et Oracle (pour l’instant, Facebook ne semble pas listé…). Pour les premiers développeurs, on trouverait Flixster, iLike, RockYou, Slide et Zlio (la société gérée par Jérémie Berrebi ) pour la France.« )
  • http://opensocialapis.blogspot.com/ ()
  • http://groups.google.com/group/opensocial-api/about
  • Developer Documentation (« The OpenSocial API is a set of common APIs for building social applications on many websites. There are two ways to access the OpenSocial API: client-side using the JavaScript API and server-side using RESTful data APIs…The People and Friends data API allows client applications to view and update People Profiles and Friend relationships using AtomPub GData APIs with a Google data schema. Your client application can request a list of a user’s Friends and query the content in an existing Profile…The Activities data API allows client applications to view and publish « actions » in the OpenSocial platform using AtomPub GData APIs with a Google data schema. Your client application can use the API to create new entries, edit or delete existing entries, and view lists of entries…The Persistence data API allows client applications to view and update key/value content using AtomPub GData APIs with a Google data schema. Your client application can edit or delete content for an existing application, user, or gadget instance, and query the content in an existing feed »)
  • http://code.google.com/apis/opensocial/articles/tutorial.html ( » This tutorial will walk you through the steps required to build a simple social gadget where you can give gifts to your friends. You can find the complete sample code in the opensocial-resources project on Google Code. This demo used the SocialNorms utilities, also part of the opensocial-resources project. These utilities encapsulate some common OpenSocial idioms, making it easier to write social gadgets. Use of SocialNorms for your own gadgets is entirely optional — if you want more control over the data exchanged, feel free to use the APIs directly. Feel free to copy the sample gadget source code and make changes as you go along. Your gadget will need to be hosted publicly, and you can use the Google Gadget Editor, Google Page Creator, Project Hosting on Google Code, or any other webhosting service to host your gadget.« )

Ajout du mercredi 7 novembre 2007. Reçu sur la liste « inuxfr-news@linuxfr.org »

o Internet: OpenSocial, un pas de plus vers une « société des réseaux sociaux »
---------------------------------------------------------------------------
Auteur: epot ( http://linuxfr.org/~epot ) @ 23:21
Thème: Communaute

    Depuis jeudi, Google Code ( http://en.wikipedia.org/wiki/Google_Code )
héberge le projet OpenSocial ( http://code.google.com/apis/opensocial/ ),
un ensemble d'API qui vont permettre le développement de programmes communs
pour un certain nombre de sites de réseaux sociaux (
http://fr.wikipedia.org/wiki/R%C3%A9seau_social ) (voir liste en référence
[1]).

Avant jeudi, tout programmeur souhaitant développer une application pour
réseaux sociaux devait apprendre l'API, la syntaxe et parfois même un
nouveau langage de chacun des réseaux (quand ceux-ci proposaient une API
accessible de l'extérieur !). Maintenant, OpenSocial permet d'accéder aux
fonctions de base, au plus petit commun dénominateur entre tous les réseaux
sociaux participant.

L'API permet ainsi d'accéder : - À l'information de profil ; - À l'information des connaissances ;
- Aux activités (événements, flux RSS, etc.).
Un des avantages d'OpenSocial est de se baser sur des langages existants
(Javascript ( http://fr.wikipedia.org/wiki/Javascript ), HTML (
http://fr.wikipedia.org/wiki/HTML ) et Flash (
http://fr.wikipedia.org/wiki/Adobe_Flash )) là où la concurrence (Facebook
( http://fr.wikipedia.org/wiki/Facebook ), pour ne pas la citer) impose
FBML ( http://wiki.developers.facebook.com/index.php/FBML ) [2] par
exemple). Le code source des exemples est sous licence libre, tout comme la
documentation. OpenSocial promet de libérer le code source nécessaire aux
API proprement dites (voir la FAQ (
http://code.google.com/apis/opensocial/faq.html ) [3]).

Finalement, on arrive petit à petit à une vraie société (ou fédération) de
réseaux sociaux, où peu importe le site/réseau dans lequel vous êtes
affilié, vous pourrez utiliser les mêmes applications (qui a parlé de
standardisation ?). Web 2.0 ( http://en.wikipedia.org/wiki/Web_2 ) [4], les
applications arrivent !

[fr] - Journal à l'origine de la dépêche ( http://linuxfr.org/redirect/54340.html )
[en] - [1] Projet OpenSocial ( http://linuxfr.org/redirect/54341.html )
[en] - [2] FBML ( http://linuxfr.org/redirect/54342.html )
[en] - [3] FAQ d'OpenSocial ( http://linuxfr.org/redirect/54343.html )
[en] - [4] Web 2.0 ( http://linuxfr.org/redirect/54344.html )
[en] - [5] Facebook and Data Control (Bruce Scheier) ( http://linuxfr.org/redirect/54345.html )

Posted in open source, REST, Web applications, web2.0 | Tagué: , , , , , , , , , | 1 Comment »

Une application Web Django (GET)…

Posted by patrick sur juillet 17, 2007

Mon précédent billet (http://pvergain.wordpress.com/2007/07/11/restful-resource-oriented-architecture-roa-http-xml/) devenant trop long je continue ici la dernière partie concernant Django.

Le titre du billet est ‘Une application Web Django (GET)...’ . Je n’ai pas mis le terme RESTful car une application Web à l’heure actuelle (juillet 2007) avec les normes HTML4 ou XHTML 1 ne peut utiliser d’autres méthodes HTTP que GET et POST ==> elle n’est donc pas RESTful.

Références pour ce problème méconnu:

  • http://cafe.elharo.com/web/why-rest-failed/ (« The problem is that GET, PUT, POST, and DELETE really are a minimal set. You truly do need all four, and we only have two; and I’ve never understood why. In 2006 browser vendors still don’t support PUT and DELETE. A few browsers over the years have tried to implement these as parts of editing functionality, but they’ve never allowed it in a real web application as opposed to a thick client GUI. The method of an HTML form is limited to GET and POST. PUT and DELETE are not allowed. This isn’t some failure of browser vendors to properly implement the specification either. The HTML specification only allows GET and POST as form actions. XHTML and even XForms 1.0 don’t change this. This means it’s impossible to build a fully RESTful client application inside a web browser. Consequently everyone tunnels everything through POST, and simply ignores PUT and DELETE »)
  • http://www.biologeek.com/journal/index.php/pour-ne-plus-etre-en-rest-comprendre-cette-architecture (« Les applications web utilisent HTTP pour permettre au serveur et au client de communiquer ensemble. … Que se passe-t-il vraiment lorsque vous tapez une adresse dans votre navigateur ? Le navigateur met en forme un message HTTP pour appeler la méthode GET de la ressource identifiée par l’URL que vous lui avez fourni. Vous pouvez aussi appeler la méthode POST à partir de votre navigateur – mais seulement s’il y a un formulaire <form> sur la page. (Ok, pas exactement grâce à AJAX mais oublions pour le moment). Les formulaires peuvent envoyer des données à une URL particulière. Lorsque vous soumettez un formulaire, le navigateur appelle la méthode POST, passant l’URL ainsi que certaines données représentant la ressource qu’il doit ajouter ou modifier. Vous ne pouvez pas appeler PUT ou DELETE avec votre navigateur avec du HTML habituel« )
  • http://groups.google.com/group/django-developers/browse_thread/thread/4278ea1ad73f68f1/e754aa3a5a4fcca2 (« but what is the recommended way to handle fake PUT and DELETE from a browser? The HttpMethodMiddleware ? Maybe a simple form/deletion in the polls application will be an interesting example for a real django case »)
  • http://www.w3.org/TR/html401/interact/forms.html#adef-method (« method = get|post [CI] This attribute specifies which HTTP method will be used to submit the form data set. Possible (case-insensitive) values are « get » (the default) and « post ». See the section on form submission for usage information »)
  • http://www.whatwg.org/specs/web-forms/current-work/#methodAndEnctypes (« The HTTP specification defines various methods that can be used with HTTP URIs. Four of these may be used as values of the method attribute: get, post, put, and delete. In this specification, these method names are applied to other protocols as well. This section defines how they should be interpreted »)

Comme on travaille sur la version de développement, on fait la mise à jour de django (cd ~/django_src; svn update):

pve@pc72 ~/django_src
$ cd ~/django_src; svn update
U django/test/client.py
U django/db/backends/postgresql_psycopg2/introspection.py
U django/conf/locale/de/LC_MESSAGES/djangojs.mo
U django/conf/locale/de/LC_MESSAGES/djangojs.po
U django/conf/locale/es_AR/LC_MESSAGES/django.po
U django/conf/locale/es_AR/LC_MESSAGES/djangojs.mo
U django/conf/locale/es_AR/LC_MESSAGES/django.mo
U django/conf/locale/es_AR/LC_MESSAGES/djangojs.po
U django/conf/locale/fr/LC_MESSAGES/djangojs.mo
U django/conf/locale/fr/LC_MESSAGES/djangojs.po
U django/conf/locale/zh_CN/LC_MESSAGES/django.po
U django/conf/locale/zh_CN/LC_MESSAGES/django.mo
U django/conf/locale/es/LC_MESSAGES/django.po
U django/conf/locale/es/LC_MESSAGES/djangojs.mo
U django/conf/locale/es/LC_MESSAGES/django.mo
U django/conf/locale/es/LC_MESSAGES/djangojs.po
U django/conf/project_template/settings.py
U django/conf/__init__.py
U django/conf/global_settings.py
U django/core/servers/basehttp.py
U django/core/urlresolvers.py
U django/core/validators.py
U django/core/management.py
U django/core/cache/backends/locmem.py
U django/newforms/fields.py
U django/contrib/comments/templatetags/comments.py
U django/contrib/admin/media/js/admin/RelatedObjectLookups.js
U django/contrib/admin/templatetags/admin_list.py
U django/contrib/admin/views/main.py
U django/contrib/localflavor/no/forms.py
U django/contrib/sessions/middleware.py
U django/utils/cache.py
U django/utils/html.py
U django/bin/make-messages.py
U django/template/defaultfilters.py
U django/middleware/common.py
U django/middleware/http.py
U tests/modeltests/str/models.py
U tests/regressiontests/forms/tests.py
U tests/regressiontests/forms/localflavor.py
A tests/regressiontests/utils
A tests/regressiontests/utils/__init__.py
A tests/regressiontests/utils/tests.py
A tests/regressiontests/utils/models.py
U tests/regressiontests/cache/tests.py
U AUTHORS
U docs/db-api.txt
U docs/newforms.txt
U docs/testing.txt
U docs/django-admin.txt
U docs/templates.txt
Updated to revision 5717.

Ensuite, on peut lancer le serveur HTTP django:

$ cd /cygdrive/e/projets/pybookmarks/; python manage.py runserver
Validating models…
0 errors found.

Django version 0.97-pre, using settings ‘pybookmarks.settings’
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

En naviguant sur l’interface d’administration, je m’aperçois qu’il faut installer la bibliothèque docutils (« Docutils is an open-source text processing system for processing plaintext documentation into useful formats, such as HTML or LaTeX. It includes reStructuredText, the easy to read, easy to use, what-you-see-is-what-you-get plaintext markup language« )

Docutils

Je le télécharge au moyen de la commande ‘svn checkout http://svn.berlios.de/svnroot/repos/docutils/trunk/docutils docutils docutils » puis je tape la commande suivante: « cd docutils; python setup.py install »

J’arrête le serveur (Ctrl+C) , je le relance (python manage.py runserver) et cette fois j’ai bien la documentation en ligne à partir du site d’administration.

Docutils

Maintenant on peut continuer à expliquer toutes les lignes du fichier ‘urls.py’: On en est à la partie 3 du tutorial django (This tutorial begins where Tutorial 2 left off. We’re continuing the Web-poll application and will focus on creating the public interface — “views.”, http://www.djangoproject.com/documentation/tutorial03/)

#!/usr/bin/python
# -*- coding: UTF-8 -*-

«  » »
If you need help with regular expressions, see Wikipedis entry
(http://en.wikipedia.org/wiki/Regular_expression)
and the Python documentation. (http://www.python.org/doc/current/lib/module-re.html)
Also, the O’Reilly book Mastering Regular Expression by Jeffrey Friedl is fantastic.

/cygdrive/e/projets/pybookmarks/urls.py
«  » »

from django.conf.urls.defaults import *
from bookmarks.views import *

urlpatterns = patterns( »,
(r’^users/([\w-]+)/$’, bookmark_list),
(r’^users/([\w-]+)/tags/$’, tag_list),
(r’^users/([\w-]+)/tags/([\w-]+)/’, tag_detail),
(r’^users/([\w-]+)/(.+)’, BookmarkDetail()),
(r’^admin/’, include(‘django.contrib.admin.urls’)),
)

L’expression: r’^users/([\w-]+)/$’ est une expression rationnelle (Pour travailler avec les expressions rationnelles, un outil graphique tel que Kodos est vraiment très pratique)

Cette expression identifie une des chaines suivantes

  • users/chomsky
    • Kodos

On l’utilise dans la navigateur Web de cette façon: http://127.0.0.1:8000/users/chomsky

Dans l’exemple du livre ‘RESTful Web Services’ on ne sert pas une page au format HTML mais au format JSON. Je vais donc modifier le fichier ‘ /cygdrive/e/projets/pybookmarks/bookmarks/views.py’ pour servir une page HTML. On étudiera donc les objets django.template (voir http://www.djangoproject.com/documentation/templates, Django’s template language is designed to strike a balance between power and ease. It’s designed to feel comfortable to those used to working with HTML. If you have any exposure to other text-based template languages, such as Smarty or CheetahTemplate, you should feel right at home with Django’s templates.).

Django template

Il faut créer la hiérarchie suivante:

template bookmarks

On crée le fichier template E:/projets/pybookmarks/bookmarks/template/bookmarks/index.html qui contient les lignes suivantes:

{% if latest_bookmark_list %}
<ul>
{% for bookmark in latest_bookmark_list %}
<li>{{ bookmark.url }}</li>
{% endfor %}
</ul>
{% else %}
<p>No bookmarks are available.</p>
{% endif %}

On ajoute les lignes suivantes au fichier views.py:

from django.template import Context, loader

on modifie la fonction « bookmark_list(request, username): »


t=loader.get_template(‘bookmarks/index.html’)
c=Context({‘latest_bookmark_list’: marks})

response = HttpResponse(t.render(c))

On modifie le fichier settings.py:

TEMPLATE_DIRS = (
# Put strings here, like « /home/html/django_templates » or « C:/www/django/templates ».
# Always use forward slashes, even on Windows.
# Don’t forget to use absolute paths, not relative paths.
« E:/projets/pybookmarks/bookmarks/template« ,
)

Et voilà ce que ça donne (j’avais auparavant introduit quelques bookmarks au moyen de l’interface administrateur http://127.0.0.1:8000/admin)

Bookmarks chomsky

Si on regarde le code source de la page on a:

     <ul>

        <li>http://www.chomsky.info/</li>

        <li>http://www.chomsky.info/audionvideo.htm</li>

        <li>http://people.csail.mit.edu/meyer/iandc-WWW/Authors/chomskynoam.html</li>

    </ul>

Ce qui est bien l’instanciation du fichier template E:/projets/pybookmarks/bookmarks/template/bookmarks/index.html

Pour l’instant notre document n’est donc pas du tout conforme aux standards du Web (emploi de XHTML, emploi des feuilles de style CSS, emploi des normes de l’accessibilité du Web). Ce sont des sujets que nous verrons un peu plus tard.

Revenons à notre problème de PUT et DELETE. Dans le fichier /cygdrive/e/projets/pybookmarks/urls.py on a la ligne suivante: (r’^users/([\w-]+)/(.+)’, BookmarkDetail()). Elle permet de lire le détail d’une URL, de détruire une URL ou de créer une URL.

On va d’abord faire un test sur ‘GET’. Je modifie le fichier /cygdrive/e/projets/pybookmarks/bookmarks/views.py pour servir du HTML plutôt que du JSON.

Je modifie la méthode BlogmarkDetail.do_GET():

t=loader.get_template(‘bookmark/index.html’)
c=Context({‘mark’: bookmark,’request’: self.request})
return HttpResponse(t.render(c))

Je crée le fichier ‘bookmark/index.html’:

{% if mark %}
<ul>
<li> {{mark.url}} </li>
<li> {{mark.user}} </li>
<li> {{mark.long_description}} </li>
</ul>
<p> La requete: </p>
<ul>
<li> Request.method={{request.method}}</li>
<li> Request.raw_post_data={{request.raw_post_data}}</li>
</ul>
{% else %}
<p>pas de bookmark.</p>
{% endif %}

Je n’ai pas àmodifier le fichier # /cygdrive/e/projets/pybookmarks/bookmarks/settings.py

Je teste avec l’URL: http://127.0.0.1:8000/users/chomsky/http://www.chomsky.info/ et j’obtiens la page HTML suivante:

Get request

Voilà pour notre premier verbe HTTP: ‘GET’.

Pour ‘POST’ nous devons passer par un formulaire (form) et c’est ce que nous verrons dans le prochain billet en étudiant le tutorial 04 (http://www.djangoproject.com/documentation/tutorial04/, « This tutorial begins where Tutorial 3 left off. We’re continuing the Web-poll application and will focus on simple form processing and cutting down our code »).

Posted in python, REST | Leave a Comment »

RESTful Resource Oriented Architecture (ROA), HTTP, URI, XML

Posted by patrick sur juillet 11, 2007

Analyse du livre « Restful web services » de Léonard Richardson et Sam Ruby, Copyright 2007, O’Reilly Media, Inc., ISBN-13: 978-0-596-52926-0.

Pour les exemples du livre on a besoin de:

– les sources du livre (http://examples.oreilly.com/9780596529260/)

Les sources du livre

– comme je suis au travail sous Windows, j’utilise l’émulateur Cygwin pour avoir un environnement de type UNIX.
– les langages semi-interprétés python, ruby, php et les langage C# et java

– différentes bibliothèques logicielles suivant les langages:

  • la bibliothèque Ruby/Amazon (Attention: « Before you can use this library, you need to obtain an Amazon Web Services developer token« ).
    • Pour l’installer
      • $ ruby setup.rb config
        —> lib
        —> lib/amazon
        —> lib/amazon/search
        —> lib/amazon/search/exchange
        <— lib/amazon/search/exchange
        <— lib/amazon/search
        <— lib/amazon
        <— lib
      • $ ruby setup.rb setup
        —> lib
        —> lib/amazon
        —> lib/amazon/search
        —> lib/amazon/search/exchange
        <— lib/amazon/search/exchange
        <— lib/amazon/search
        <— lib/amazon
        <— lib
      • $ ruby setup.rb install
        —> lib
        mkdir -p /usr/lib/ruby/site_ruby/1.8/
        install amazon.rb /usr/lib/ruby/site_ruby/1.8/
        —> lib/amazon
        mkdir -p /usr/lib/ruby/site_ruby/1.8/amazon
        install search.rb /usr/lib/ruby/site_ruby/1.8/amazon
        install wishlist.rb /usr/lib/ruby/site_ruby/1.8/amazon
        install weddingregistry.rb /usr/lib/ruby/site_ruby/1.8/amazon
        install babyregistry.rb /usr/lib/ruby/site_ruby/1.8/amazon
        install transaction.rb /usr/lib/ruby/site_ruby/1.8/amazon
        install locale.rb /usr/lib/ruby/site_ruby/1.8/amazon
        install shoppingcart.rb /usr/lib/ruby/site_ruby/1.8/amazon
        —> lib/amazon/search
        mkdir -p /usr/lib/ruby/site_ruby/1.8/amazon/search
        install seller.rb /usr/lib/ruby/site_ruby/1.8/amazon/search
        install blended.rb /usr/lib/ruby/site_ruby/1.8/amazon/search
        install exchange.rb /usr/lib/ruby/site_ruby/1.8/amazon/search
        install cache.rb /usr/lib/ruby/site_ruby/1.8/amazon/search
        —> lib/amazon/search/exchange
        mkdir -p /usr/lib/ruby/site_ruby/1.8/amazon/search/exchange
        install marketplace.rb /usr/lib/ruby/site_ruby/1.8/amazon/search/exchange
        install thirdparty.rb /usr/lib/ruby/site_ruby/1.8/amazon/search/exchange
        <— lib/amazon/search/exchange
        <— lib/amazon/search
        <— lib/amazon
        <— lib
  • la commande s3sh pour Ruby (http://amazon.rubyforge.org/ , AWS::S3 A Ruby Library for Amazon’s Simple Storage Service’s (S3) REST API).
    • pve@pc72 /cygdrive/e/Temp/rubygems-0.9.4/rubygems-0.9.4
      $ gem i aws-s3 -ry
      Bulk updating Gem source index for: http://gems.rubyforge.org
      Successfully installed aws-s3-0.4.0
      Successfully installed xml-simple-1.0.11
      Successfully installed builder-2.1.2
      Successfully installed mime-types-1.15
      Installing ri documentation for aws-s3-0.4.0…
      Installing ri documentation for builder-2.1.2…
      Installing ri documentation for mime-types-1.15…
      Installing RDoc documentation for aws-s3-0.4.0…
      Installing RDoc documentation for builder-2.1.2…
      Installing RDoc documentation for mime-types-1.15…
      pve@pc72 /cygdrive/e/Temp/rubygems-0.9.4/rubygems-0.9.4

Test du premier programme ruby:

#!/usr/bin/ruby -w
# amazon-book-search.rb
require ‘amazon/search’

if ARGV.size != 2
puts « Usage: #{$0} [Amazon Web Services AccessKey ID] [text to search for] »
exit
end
access_key, search_request = ARGV

req = Amazon::Search::Request.new(access_key)
# For every book in the search results…
req.keyword_search(search_request, ‘books’, Amazon::Search::LIGHT) do |book|
# Print the book’s name and the list of authors.
puts %{« #{book.product_name} » by #{book.authors.join(‘, ‘)}}
end

  • $ ruby amazon-book-search.rb 126116STACCESSID « restful web services »
    « RESTful Web Services » by Leonard Richardson, Sam Ruby, David Heinemeier Hansson

Bon j’ai détaillé ce premier exemple car je n’avais encore jamais travaillé avec Ruby. Donc quittons cet aspect très pratique pour entrer dans l’aspect plus théorique du livre.

Les auteurs introduisent la notion de « Web programmable » qui est basée sur d’abord et avant tout sur le protocole HTTP et XML (éventuellement HTML, JSON, du texte et du binaire). « If you don’t use HTTP, you’re not on the web« . Il y a donc tout un paragraphe (« HTTP: Documents in Envelopes ») sur HTTP. On y apprend que à part les méthodes GET et POST que tout le monde connait 🙂 il y a les méthodes beaucoup plus méconnues que sont HEAD, PUT et DELETE sans compter OPTIONS, TRACE et CONNECT. La méthode ‘GET’ permet de rechercher une ressource, la commande ‘DELETE’ permet de la détruire tandis que la commande ‘PUT’ permet de la mettre à jour.

On en vient à l’exemple de recherche de photos sur flickr (http://www.flickr.com/services/api/keys/apply. On sait qu’on fait une recherche de ressources grâce à l’emploi du nom de la méthode ‘flickr.photos.search’ qui fait référence à la méthode HTTP GET.

Il y a une comparaison entre les 2 URIS équivalentes suivantes:

http://flickr.com/photos/tags/penguin –> la méthode est ‘GET’ et l’information de portée (scoping information) est ‘les photos taggés penguin’

-http://api.flickr.com/services/rest/?method=flickr.photos.search&api_key=xxx&tags=penguin (dans le bouquin ils ont oublié de mettre &api_key=xxx) –> la méthode est ‘recherche une photo’ et l’information de portée est ‘penguin’.

Il n’y a pas de différence technique entre les 2 URIs mais il y a une différence au niveau de l’architecture si on emploie une méthode comme ‘flickr.photos.delete’ qui utilisera la méthode HTTP GET à une place qui ne lui était pas destinée (‘into places it wasn’t meant to go’). On a une architecture REST-RPC hybride (p.16)

A partir de là (« RESTful, Resource-Oriented Architectures(ROA), page 13), les auteurs définissent ce qu’ils entendent par de véritables services web Restful: ce sont des services qui resemblent au web et ils les appellent ‘Orientés ressource’ (resource oriented’).

Dans des architectures RESTful ‘Orientées Ressource’ l’information de portée est dans l’URI et l’architecture est RESTful car la méthode d’information est la méthode HTTP. Si l’information de portée (scoping information) n’est pas dans l’URI alors le service n’est pas ‘Orienté Ressource’.

Les services suivants sont considérés comme étant ‘RESTFul, orientés ressource‘:

tandis que les suivants sont considérés comme REST-RPC hybrid:

  • l’API del.icio.us
  • l’API « REST » de flickr
  • la plupart des applications web

Fin du chapitre 1 (ch1)

Dans le chapitre 2 (« Writing Web Service Clients ») on confirme que l’API del.icio.us n’utilise que la méthode HTTP ‘GET’ quel que soit le service demandé ! Le chapitre 7 « A service implementation » montrera ce qu’est un service RESTful pour le service del.icio.us.

Le but de ce chapitre est d’écrire des clients del.icio.us à l’aide de différents langages et d’utiliser en conséquence différentes bibliothèques permettant de faire des requêtes HTTP. Ces bibliothèques doivent respecter ces caractéristiques:

– le support de HTTPS et du certificat SSL

– implémenter au moins les 5 méthodes HTTP suivantes: GET, HEAD, POST, PUT et DELETE. On rappelle que malheureusement certaines bibliothèques ne supportent que GET et POST et parfois même uniquement GET ! Les méthodes comme OPTIONS , TRACE et la méthode MOVE du protocole Webdav sont un bonus.

– doit permettre au programmeur de manipuler les données envoyées lors d’une requête PUT ou POST

– doit permettre au programmeur de modifier les headers HTTP

– doit donner au programmeur au code retour et aux headers HTTP de la réponse

– doit pouvoir communiquer au travers d’un serveur mandataire HTTP.

– etc.

La bibliothèque standard de Ruby (open-uri) ne supporte que la méthode ‘GET’. Sam Ruby a écrit rest-open-uri

$ gem install rest-open-uri
Successfully installed rest-open-uri-1.0.0
Installing ri documentation for rest-open-uri-1.0.0…
Installing RDoc documentation for rest-open-uri-1.0.0…

Pour Python, il y a urllib2 (semblable à open-uri), httplib et l’excellente bibliothèque de Joe Gregorio httplib2 (http://bitworking.org/projects/httplib2) supportant pratiquement toutes les caractéristiques d’une bonne bibliothèqueHTTP.

pve@pc72 /cygdrive/e/Temp/httplib2-0.3.0
$ python setup.py install
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/httplib2
copying httplib2/__init__.py -> build/lib/httplib2
copying httplib2/iri2uri.py -> build/lib/httplib2
running install_lib
creating /usr/lib/python2.5/site-packages/httplib2
running install_egg_info
Writing /usr/lib/python2.5/site-packages/httplib2-0.3.0-py2.5.egg-info

Je passe sur Java et C#. Pour PHP, il y a libcurl; pour Javascript XMLHttpRequest (voir chapitre 11).

En ligne de commande on a cURL (http://curl.haxx.se) qui est livré en standard sous cygwin. Utiliser l’option -v de cURL permet d’avoir des informations très intéressantes.

Pour info: lynx est aussi un outil intéressant pour les apllications web.
On passe ensuite aux parsers XML

– Ruby: REXML(interfaces DOM et SAX, support XPath). Attention: ne rejette pas le XML mal formé. Autres bibliohèques: libxml2 du projet GNOME, hpricot

$ gem install hpricot
Select which gem to install for your platform (i386-cygwin)
1. hpricot 0.6 (mswin32)
2. hpricot 0.6 (jruby)
3. hpricot 0.6 (ruby)
4. hpricot 0.5 (ruby)
5. hpricot 0.5 (mswin32)
6. Skip this gem
7. Cancel installation
> 3
Building native extensions. This could take a while…
Successfully installed hpricot-0.6
Installing ri documentation for hpricot-0.6…
Installing RDoc documentation for hpricot-0.6…

– Python: ElementTree (support XPath limité), 4Suite (support complet de XPath, http://4suite.org), …etc.

Pour le format JSON, voir le site http://www.json.org.

On finit le chapitre par WADL. Voir le site http://tomayac.de/rest-describe/latest/RestDescribe.html.

Fin du chapitre 2.

Chapitre 3, « What makes Restful services different ? »

Les auteurs rappellent que les APIs del.icio.us et Flickr marchent comme le web lorsqu’il s’agit de rechercher des données mais que ce sont des services de style RPC lorsqu’il s’agit de modifier des données. Les différents services de recherche Yahoo! sont très RESTful mais ils sont si simples qu’il ne peuvent servir d’exemples. Par contre le protocole de publication Atom (APP) et le service de stockage simple d’Amazon (S3) décrit dans ce chapitre sont RESTful et orientés ressources. Amazon fournit des biblothèques d’accès à ce service pour différents langages et outils (comme cURL) (http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=47)

Le service S3 RESTful expose toutes les fonctionnalités du service style RPC mais au lieu de le faire avec des noms de fonction spécialisées il expose des objets standards HTTP appelés ‘ressources‘. Au lieu de répondre à des noms de fonctions comme ‘getObjects’ une ressource répond à une ou plusieurs des 4 méthodes HTTP standards: GET, HEAD, PUT et DELETE.

– Pour avoir la valeur d’un objet on envoie la requête ‘GET’ sur l’URI de cet objet

– pour obtenir uniquement les métadonnées de cet objet on envoie la requête ‘HEAD’ sur la même URI

– pour créer un ‘bucket’, on envoie la requête ‘PUT’ sur l’URI de l’objet contenant le nom du bucket

– pour détruire un ‘bucket’ ou un autre objet, on envoie la requête ‘DELETE’ sur l’URI correspondante.

Les concepteurs de S3 n’ont rien fait d’extraordinaire. Suivant le standard HTTP c’est pour faire ce genre de choses que les méthodes GET, HEAD, PUT et DELETE ont été créées !

Les codes de réponse HTTP pour S3 vont de 200 (« OK »), 404 (« NotFound »). La plus commune est 403 (« Forbidden »). S3 utilise aussi les codes 400 (« Bad request ») indiquant que le serveur ne comprend pas les données envoyées par le client, 409 (« Conflict ») envoyé au client qui essaye de détruire un bucket qui n’est pas vide.

Ensuite on crée une bibliothèque Ruby pour impléménter un client S3. Le but est d’illustrer la théorie derrière REST. Au lieu d’utiliser des noms de méthodes spécifiques, on utilisera des noms qui reflèteront l’architecture RESTful: get, put, delete etc… Les auteurs créent un module nommé S3::Authorized dans le fichier S3lib.rb qu’il faut modifier pour entrer sa clé publique et sa clé privée (« Enter your public key (Amazon calls it an « Access Key ID ») and your private key (Amazon calls it a « Secret Access Key ». This is so you can sign your S3 requests and Amazon will know who to charge »)

Je vérifie avec curl la validité de mes clés.

pve@pc72 ~
$ cat > pubkey.txt <<EOF
> 1261ffffffffff8X19802
> EOF

pve@pc72 ~
$ cat > key.txt <<EOF
> tmaTMgnMiyyyyyyyyyyypMCV8O9JdxQ4
> EOF
$ curl -v –key key.txt –pubkey pubkey.txt https://s3.amazonaws.com/
* About to connect() to s3.amazonaws.com port 443 (#0)
* Trying 72.21.203.129… connected
* Connected to s3.amazonaws.com (72.21.203.129) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: /usr/share/curl/curl-ca-bundle.crt
CApath: none
* SSLv2, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using RC4-MD5
* Server certificate:
* subject: /C=US/ST=Washington/L=Seattle/O=Amazon.com Inc./CN=s3.amazonaw
s.com
* start date: 2007-02-20 00:00:00 GMT
* expire date: 2008-02-20 23:59:59 GMT
* common name: s3.amazonaws.com (matched)
* issuer: /C=US/O=RSA Data Security, Inc./OU=Secure Server Certification
Authority
* SSL certificate verify ok.
> GET / HTTP/1.1
> User-Agent: curl/7.16.3 (i686-pc-cygwin) libcurl/7.16.3 OpenSSL/0.9.8e zlib/1.
2.3 libssh2/0.15-CVS
> Host: s3.amazonaws.com
> Accept: */*
>
< HTTP/1.1 307 Temporary Redirect
< x-amz-id-2: PyFBRRXn6ohqSTY/OdVyE54dsts1bEsUPYluggqw67RWYEhGBrDl3Ru55piRhIgf
< x-amz-request-id: 4546F4FDF40D80AF
< Date: Wed, 11 Jul 2007 10:27:39 GMT
< Location: http://aws.amazon.com/s3
< Content-Length: 0
< Server: AmazonS3
<
* Connection #0 to host s3.amazonaws.com left intact
* Closing connection #0
* SSLv3, TLS alert, Client hello (1):

J’ai un problème avec le client ruby:

pve@pc72 /cygdrive/e/projets/REST/ruby/ch3
$ ruby s3-sample-client.rb buck1 obj1 5
/usr/lib/ruby/1.8/net/http.rb:567: warning: using default DH parameters.
/usr/lib/ruby/gems/1.8/gems/rest-open-uri-1.0.0/lib/rest-open-uri.rb:320
n_http’: 403 Forbidden (OpenURI::HTTPError)
from /usr/lib/ruby/gems/1.8/gems/rest-open-uri-1.0.0/lib/rest-op
b:659:in `buffer_open’
……
b:162:in `open_uri’
from /usr/lib/ruby/gems/1.8/gems/rest-open-uri-1.0.0/lib/rest-op
b:561:in `open’
from /usr/lib/ruby/gems/1.8/gems/rest-open-uri-1.0.0/lib/rest-op
b:35:in `open’
from ./S3lib.rb:276:in `open’
from ./S3lib.rb:45:in `get’
from s3-sample-client.rb:13

Ensuite on a un exemple d’utilisation de Ruby on rails pour la création de services RESTful. On installe donc Ruby on rails avec la commande ‘gem install rails’

$ gem install rails
Need to update 13 gems from http://gems.rubyforge.org
………….
complete
Install required dependency rake? [Yn] Y
Install required dependency activesupport? [Yn] Y
Install required dependency activerecord? [Yn] Y
Install required dependency actionpack? [Yn] Y
Install required dependency actionmailer? [Yn] Y
Install required dependency actionwebservice? [Yn] Y
Successfully installed rails-1.2.3
Successfully installed rake-0.7.3
Successfully installed activesupport-1.4.2
Successfully installed activerecord-1.15.3
Successfully installed actionpack-1.13.3
Successfully installed actionmailer-1.3.3
Successfully installed actionwebservice-1.2.3
Installing ri documentation for rake-0.7.3…
Installing ri documentation for activesupport-1.4.2…
Installing ri documentation for activerecord-1.15.3…
Installing ri documentation for actionpack-1.13.3…
Installing ri documentation for actionmailer-1.3.3…
Installing ri documentation for actionwebservice-1.2.3..
Installing RDoc documentation for rake-0.7.3…
Installing RDoc documentation for activesupport-1.4.2…
Installing RDoc documentation for activerecord-1.15.3…
Installing RDoc documentation for actionpack-1.13.3…
Installing RDoc documentation for actionmailer-1.3.3…
Installing RDoc documentation for actionwebservice-1.2.3

pve@pc72 /cygdrive/e/projets/REST/ruby/ch3

On apprend que:

– dans une application Rails, le modèle et le contrôleur du modèle MVC peuvent se comporter comme un service web RESTful. L’interface d’ActiveResource est analogue à l’interface d’ActiveRecord: avec ActiveRecord les objets sont dans une base de données et sont exposés au moyen de SQL avec les commandes SELECT, INSERT, UPDATE et DELETE. Avec ActiveResource ils sont au sein d’une application Rails, exposés au moyen de HTTP avec les commandes GET, POST, PUT et DELETE.

En conclusion, un clone de S3 en Ruby : http://code.whytheluckystiff.net/parkplace

Chapitre 4: The Resource-Oriented Architecture (ROA)

L’architecture ROA est une façon de transformer un problème en service web RESTful: un ensemble d’URIs, d’HTTP et de XML qui marchent comme le reste du web et que les programmeurs aimeront 🙂

Les services Web RESTful peuvent être classés suivant les réponses à 2 questions:

– l’information de portée est stockée dans l’URI : (pourquoi le serveur enverrait cette information plutôt qu’une autre ?) C’est le principe d’adressabilité.

– la méthode d’information est la méthode HTTP (pourquoi le serveur devrait-il envoyer cette donnée au lieu de la détruire ?)

Pour les auteurs, REST n’est pas une architecture (ce qui est en contradiction avec la définition donnée par Wikipedia) mais un ensemble de critères de conception. Je ne vais pas plus loin dans leur définition car elle est en contradiction totale de ce que je lis sur Wikipedia. Les auteurs estiment que REST n’a pas de rapport direct avec HTTP et les URIs.

Quelques définitions:

– à une ressource doit correpondre au moins une URI. L’URI est le nom et l’adresse de la ressource. Je fais remarquer que le U dans URI veut dire Uniform et non Universal et ce depuis décembre 1994 (voir http://tools.ietf.org/html/rfc1738)

– une URI devrait être descriptive et avoir une structure (c’est donc une convention à adopter)

– 2 ressources ne peuvent avoir la même URI

– une ressource peut avoir 1 ou plusieurs URI

– une URI désigne par définition une et une seule ressource

– une application est adressable si elle expose ses données en tant que ressources

– le fait d’avoir une URI pour chaque ressource permet l’utilisation de mandataires HTTP (proxies HTTP) pour la mise en cache des ressources

– une requête HTTP est sans état (statelessness)

– une ressource est une source de représentations multiples

– pour désigner des représentations différentes les auteurs recommandent de leur attribuer une URI distincte. Exemple: ajouter un .es, .en, .fr suivant la langue. Une alternative est la négociation du contenu (content negociation, voir les champs HTTP header: Accept-Language et Accept).

Ici les auteurs abordent la notion d’interface uniforme:

– pour lire une ressource on utilise la requête ‘GET

   The GET method means retrieve whatever information (in the form of an
   entity) is identified by the Request-URI. If the Request-URI refers
   to a data-producing process, it is the produced data which shall be
   returned as the entity in the response and not the source text of the
   process, unless that text happens to be the output of the process.

   The semantics of the GET method change to a "conditional GET" if the
   request message includes an If-Modified-Since, If-Unmodified-Since,
   If-Match, If-None-Match, or If-Range header field. A conditional GET
   method requests that the entity be transferred only under the
   circumstances described by the conditional header field(s). The
   conditional GET method is intended to reduce unnecessary network
   usage by allowing cached entities to be refreshed without requiring
   multiple requests or transferring data already held by the client.

   The semantics of the GET method change to a "partial GET" if the
   request message includes a Range header field. A partial GET requests
   that only part of the entity be transferred, as described in section
   14.35. The partial GET method is intended to reduce unnecessary
   network usage by allowing partially-retrieved entities to be
   completed without transferring data already held by the client.

   The response to a GET request is cacheable if and only if it meets
   the requirements for HTTP caching described in section 13

– pour supprimer une ressource on utilise la requête ‘DELETE’

   The DELETE method requests that the origin server delete the resource
   identified by the Request-URI. This method MAY be overridden by human
   intervention (or other means) on the origin server. The client cannot
   be guaranteed that the operation has been carried out, even if the
   status code returned from the origin server indicates that the action
   has been completed successfully. However, the server SHOULD NOT
   indicate success unless, at the time the response is given, it
   intends to delete the resource or move it to an inaccessible
   location.

   A successful response SHOULD be 200 (OK) if the response includes an
   entity describing the status, 202 (Accepted) if the action has not
   yet been enacted, or 204 (No Content) if the action has been enacted
   but the response does not include an entity.

   If the request passes through a cache and the Request-URI identifies
   one or more currently cached entities, those entries SHOULD be
   treated as stale. Responses to this method are not cacheable.

– pour créer ou modifier une ressource utiliser la requête ‘PUT‘ associée à l’URI

   The PUT method requests that the enclosed entity be stored under the
   supplied Request-URI. If the Request-URI refers to an already
   existing resource, the enclosed entity SHOULD be considered as a
   modified version of the one residing on the origin server. If the
   Request-URI does not point to an existing resource, and that URI is
   capable of being defined as a new resource by the requesting user
   agent, the origin server can create the resource with that URI. If a
   new resource is created, the origin server MUST inform the user agent
   via the 201 (Created) response. If an existing resource is modified,
   either the 200 (OK) or 204 (No Content) response codes SHOULD be sent
   to indicate successful completion of the request. If the resource
   could not be created or modified with the Request-URI, an appropriate
   error response SHOULD be given that reflects the nature of the
   problem. The recipient of the entity MUST NOT ignore any Content-*
   (e.g. Content-Range) headers that it does not understand or implement
   and MUST return a 501 (Not Implemented) response in such cases.

   If the request passes through a cache and the Request-URI identifies
   one or more currently cached entities, those entries SHOULD be
   treated as stale. Responses to this method are not cacheable.

   The fundamental difference between the POST and PUT requests is
   reflected in the different meaning of the Request-URI. The URI in a
   POST request identifies the resource that will handle the enclosed
   entity. That resource might be a data-accepting process, a gateway to
   some other protocol, or a separate entity that accepts annotations.
   In contrast, the URI in a PUT request identifies the entity enclosed
   with the request -- the user agent knows what URI is intended and the
   server MUST NOT attempt to apply the request to some other resource.
   If the server desires that the request be applied to a different URI,

Fielding, et al.            Standards Track                    [Page 55]
 
RFC 2616                        HTTP/1.1                       June 1999

   it MUST send a 301 (Moved Permanently) response; the user agent MAY
   then make its own decision regarding whether or not to redirect the
   request.

   A single resource MAY be identified by many different URIs. For
   example, an article might have a URI for identifying "the current
   version" which is separate from the URI identifying each particular
   version. In this case, a PUT request on a general URI might result in
   several other URIs being defined by the origin server.

   HTTP/1.1 does not define how a PUT method affects the state of an
   origin server.

– pour retrouver les métadata d’une ressource utiliser la requête ‘HEAD‘. Un client peut utiliser cette requête pour voir si une requête existe.

   The HEAD method is identical to GET except that the server MUST NOT
   return a message-body in the response. The metainformation contained
   in the HTTP headers in response to a HEAD request SHOULD be identical
   to the information sent in response to a GET request. This method can
   be used for obtaining metainformation about the entity implied by the
   request without transferring the entity-body itself. This method is
   often used for testing hypertext links for validity, accessibility,
   and recent modification.

   The response to a HEAD request MAY be cacheable in the sense that the
   information contained in the response MAY be used to update a
   previously cached entity from that resource. If the new field values
   indicate that the cached entity differs from the current entity (as
   would be indicated by a change in Content-Length, Content-MD5, ETag
   or Last-Modified), then the cache MUST treat the cache entry as
   stale.

– pour savoir quelles opérations sont permises sur une ressource employer la requête ‘OPTIONS‘. Bon c’est de la théorie puisque très peu de serveurs offrent ce support.

   The OPTIONS method represents a request for information about the
   communication options available on the request/response chain
   identified by the Request-URI. This method allows the client to
   determine the options and/or requirements associated with a resource,
   or the capabilities of a server, without implying a resource action
   or initiating a resource retrieval.

   Responses to this method are not cacheable.

   If the OPTIONS request includes an entity-body (as indicated by the
   presence of Content-Length or Transfer-Encoding), then the media type
   MUST be indicated by a Content-Type field. Although this
   specification does not define any use for such a body, future
   extensions to HTTP might use the OPTIONS body to make more detailed
   queries on the server. A server that does not support such an
   extension MAY discard the request body.

   If the Request-URI is an asterisk ("*"), the OPTIONS request is
   intended to apply to the server in general rather than to a specific
   resource. Since a server's communication options typically depend on
   the resource, the "*" request is only useful as a "ping" or "no-op"
   type of method; it does nothing beyond allowing the client to test
   the capabilities of the server. For example, this can be used to test
   a proxy for HTTP/1.1 compliance (or lack thereof).

   If the Request-URI is not an asterisk, the OPTIONS request applies
   only to the options that are available when communicating with that
   resource.

   A 200 response SHOULD include any header fields that indicate
   optional features implemented by the server and applicable to that
   resource (e.g., Allow), possibly including extensions not defined by
   this specification. The response body, if any, SHOULD also include
   information about the communication options. The format for such a

Fielding, et al.            Standards Track                    [Page 52]
 
RFC 2616                        HTTP/1.1                       June 1999

   body is not defined by this specification, but might be defined by
   future extensions to HTTP. Content negotiation MAY be used to select
   the appropriate response format. If no response body is included, the
   response MUST include a Content-Length field with a field-value of
   "0".

   The Max-Forwards request-header field MAY be used to target a
   specific proxy in the request chain. When a proxy receives an OPTIONS
   request on an absoluteURI for which request forwarding is permitted,
   the proxy MUST check for a Max-Forwards field. If the Max-Forwards
   field-value is zero ("0"), the proxy MUST NOT forward the message;
   instead, the proxy SHOULD respond with its own communication options.
   If the Max-Forwards field-value is an integer greater than zero, the
   proxy MUST decrement the field-value when it forwards the request. If
   no Max-Forwards field is present in the request, then the forwarded
   request MUST NOT include a Max-Forwards field.

– la requête HTTP ‘POST‘ est la plus mal comprise des méthodes HTTP:

   The POST method is used to request that the origin server accept the
   entity enclosed in the request as a new subordinate of the resource
   identified by the Request-URI in the Request-Line. POST is designed
   to allow a uniform method to cover the following functions:

      - Annotation of existing resources;

      - Posting a message to a bulletin board, newsgroup, mailing list,
        or similar group of articles;

      - Providing a block of data, such as the result of submitting a
        form, to a data-handling process;

      - Extending a database through an append operation.

   The actual function performed by the POST method is determined by the
   server and is usually dependent on the Request-URI. The posted entity
   is subordinate to that URI in the same way that a file is subordinate
   to a directory containing it, a news article is subordinate to a
   newsgroup to which it is posted, or a record is subordinate to a
   database.

   The action performed by the POST method might not result in a
   resource that can be identified by a URI. In this case, either 200
   (OK) or 204 (No Content) is the appropriate response status,
   depending on whether or not the response includes an entity that
   describes the result.

Fielding, et al.            Standards Track                    [Page 54]
 
RFC 2616                        HTTP/1.1                       June 1999

   If a resource has been created on the origin server, the response
   SHOULD be 201 (Created) and contain an entity which describes the
   status of the request and refers to the new resource, and a Location
   header (see section 14.30).

   Responses to this method are not cacheable, unless the response
   includes appropriate Cache-Control or Expires header fields. However,
   the 303 (See Other) response can be used to direct the user agent to
   retrieve a cacheable resource.

Dans une conception RESTful, la méthode ‘POST’ signifie ‘ajouter’ (append) une ressource à une ressource existante. La différence entre ‘PUT’ et ‘POST’ est la suivante: le client utilise la méthode ‘PUT’ lorsque c’est le client qui décide de l’URI de la ressource; le client utilise la méthode ‘POST’ lorsque c’est le serveur qui décide de l’URI qui identifiera la nouvelle ressource. Autrement dit la méthode ‘POST est une façon de créer une nouvelle ressource sans que le client ait la connaissance exacte de sa future URI. Dans la plupart des cas, le client connait l’URI du parent de la ressource. La réponse à ce type de POST est généralement 201 (‘Created’). Une fois que cette ressource exist, l’URI est définie et le client peut utiliser les méthodes ‘PUT’, ‘GET’ et ‘DELETE’.

Mais la signification que 99,9% des développeurs connaissent est le ‘POST’ surchargé: c’est la fameuse requête ‘POST’ employée dans les formulaires HTML: l’information sur ce qui doit être fait est contenue dans la requête HTTP (URI, entêtes HTTP, ou le corps de la requête). C’est d’après les auteurs une chose inévitable…!

– GET et HEAD sont des méthodes sûres (safe).

   Implementors should be aware that the software represents the user in
   their interactions over the Internet, and should be careful to allow
   the user to be aware of any actions they might take which may have an
   unexpected significance to themselves or others.

   In particular, the convention has been established that the GET and
   HEAD methods SHOULD NOT have the significance of taking an action
   other than retrieval. These methods ought to be considered "safe".
   This allows user agents to represent other methods, such as POST, PUT
   and DELETE, in a special way, so that the user is made aware of the
   fact that a possibly unsafe action is being requested.

   Naturally, it is not possible to ensure that the server does not
   generate side-effects as a result of performing a GET request; in
   fact, some dynamic resources consider that a feature. The important
   distinction here is that the user did not request the side-effects,
   so therefore cannot be held accountable for them.

– GET, HEAD, PUT et DELETE sont idempotentes.

   Methods can also have the property of "idempotence" in that (aside
   from error or expiration issues) the side-effects of N > 0 identical
   requests is the same as for a single request. The methods GET, HEAD,
   PUT and DELETE share this property. Also, the methods OPTIONS and
   TRACE SHOULD NOT have side effects, and so are inherently idempotent.

Fielding, et al.            Standards Track                    [Page 51]
RFC 2616                        HTTP/1.1                       June 1999

   However, it is possible that a sequence of several requests is non-
   idempotent, even if all of the methods executed in that sequence are
   idempotent. (A sequence is idempotent if a single execution of the
   entire sequence always yields a result that is not changed by a
   reexecution of all, or part, of that sequence.) For example, a
   sequence is non-idempotent if its result depends on a value that is
   later modified in the same sequence.

   A sequence that never has side effects is idempotent, by definition
   (provided that no concurrent operations are being executed on the
   same set of resources).

– la méthode ‘POST’ n’est ni sûre (safe) ni idempotente.

– les auteurs signalent que la méthode ‘GET’ n’a pas été utilisée correctement sur le Web, cette méthode pouvant être unsafe ! Voir Google et son WebAccelerator de 2005.

– les auteurs finissent en constatant que actuellement les formulaires HTML n’autorisent que POST et GET (p.153 les auteurs utilisent ‘PUT’ et ‘DELETE’ qui font partie de la future norme XHTM5, voir http://cafe.elharo.com/web/why-rest-failed/ )

http://www.w3.org/TR/html401/interact/forms.html#adef-method

method = get|post [CI]
This attribute specifies which HTTP method will be used to submit the form data set. Possible (case-insensitive) values are « get » (the default) and « post ». See the section on form submission for usage information.

http://www.whatwg.org/specs/web-forms/current-work/#methodAndEnctypes

« The HTTP specification defines various methods that can be used with HTTP URIs. Four of these may be used as values of the method attribute: get, post, put, and delete. In this specification, these method names are applied to other protocols as well. This section defines how they should be interpreted.

If the specified method is not one of get, post, put, or delete then it is treated as get in the tables below. »

Chapitre 5: « Designing Read_only Resource-Oriented Services

D’abord on définit son ensemble de données (Data Set) et on décide de découper ses données en ressources. Au lieu de penser en termes d’actions, il faut penser en termes de résultats d’une action.

Ensuite, il faut nommer ces ressources (« Name the Resources »). Il faut se rappeler que dans un service orienté ressources, l’URI contient toutes les informations de portée. Quelques conseils:

– utiliser les chemins pour encoder une hiérarchie: /parent/enfant

– utiliser des caractères de ponctuation pour éviter d’employer à nouveau une hiérarchie: /parent/enfant1;enfant2

– utiliser des variables de recherche pour indiquer que l’on attend des entrées: /search?q=cyliste&name=poupou

Maintenant, il faut décider quelles données renvoyées au client et quels formats employer pour ces données (choix de la représentation) lorsqu’un client demande une ressource. Le principal but d’une représentation est de transmettre l’état de la ressource. Une représentation peut être au format XML (avec un vocabulaire spécifique comme XHTML, ATOM, …etc)

En ce qui concerne les réponses HTTP on aura:

– 200 (« OK)

– le Content-Type de l’entête HTTP sera: application/xhtml+xml pour les résultats de recherche et image/png pour les images.

– les auteurs parlent de la méthode ‘GET’ conditionnelle. Il faut utiliser les champs ‘Last-Modified‘, ‘If-Modified-Since‘, la réponse 304 (« Not Modified ») permettant de ne pas recharger une donnée qui n’a pas changée. Voir Chapitre 8 pour plus de détails.



14.25 If-Modified-Since

   The If-Modified-Since request-header field is used with a method to
   make it conditional: if the requested variant has not been modified
   since the time specified in this field, an entity will not be
   returned from the server; instead, a 304 (not modified) response will
   be returned without any message-body.

       If-Modified-Since = "If-Modified-Since" ":" HTTP-date

Fielding, et al.            Standards Track                   [Page 130]
 
RFC 2616                        HTTP/1.1                       June 1999

   An example of the field is:

       If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT

   A GET method with an If-Modified-Since header and no Range header
   requests that the identified entity be transferred only if it has
   been modified since the date given by the If-Modified-Since header.
   The algorithm for determining this includes the following cases:

      a) If the request would normally result in anything other than a
         200 (OK) status, or if the passed If-Modified-Since date is
         invalid, the response is exactly the same as for a normal GET.
         A date which is later than the server's current time is
         invalid.

      b) If the variant has been modified since the If-Modified-Since
         date, the response is exactly the same as for a normal GET.

      c) If the variant has not been modified since a valid If-
         Modified-Since date, the server SHOULD return a 304 (Not
         Modified) response.

   The purpose of this feature is to allow efficient updates of cached
   information with a minimum amount of transaction overhead.

      Note: The Range request-header field modifies the meaning of If-
      Modified-Since; see section 14.35 for full details.

      Note: If-Modified-Since times are interpreted by the server, whose
      clock might not be synchronized with the client.

      Note: When handling an If-Modified-Since header field, some
      servers will use an exact date comparison function, rather than a
      less-than function, for deciding whether to send a 304 (Not
      Modified) response. To get best results when sending an If-
      Modified-Since header field for cache validation, clients are
      advised to use the exact date string received in a previous Last-
      Modified header field whenever possible.

      Note: If a client uses an arbitrary date in the If-Modified-Since
      header instead of a date taken from the Last-Modified header for
      the same request, the client should be aware of the fact that this
      date is interpreted in the server's understanding of time. The
      client should consider unsynchronized clocks and rounding problems
      due to the different encodings of time between the client and
      server. This includes the possibility of race conditions if the
      document has changed between the time it was first requested and
      the If-Modified-Since date of a subsequent request, and the

Fielding, et al.            Standards Track                   [Page 131]
 
RFC 2616                        HTTP/1.1                       June 1999

      possibility of clock-skew-related problems if the If-Modified-
      Since date is derived from the client's clock without correction
      to the server's clock. Corrections for different time bases
      between client and server are at best approximate due to network
      latency.

   The result of a request having both an If-Modified-Since header field
   and either an If-Match or an If-Unmodified-Since header fielfields is
   undefined by this specification

10.3.5 304 Not Modified

If the client has performed a conditional GET request and access is
allowed, but the document has not been modified, the server SHOULD
respond with this status code. The 304 response MUST NOT contain a
message-body, and thus is always terminated by the first empty line
after the header fields.

The response MUST include the following header fields:

- Date, unless its omission is required by section 14.18.1

Fielding, et al. Standards Track [Page 63]

RFC 2616 HTTP/1.1 June 1999

If a clockless origin server obeys these rules, and proxies and
clients add their own Date to any response received without one (as
already specified by [RFC 2068], section 14.19), caches will operate
correctly.

- ETag and/or Content-Location, if the header would have been sent
in a 200 response to the same request

- Expires, Cache-Control, and/or Vary, if the field-value might
differ from that sent in any previous response for the same
variant

If the conditional GET used a strong cache validator (see section
13.3.3), the response SHOULD NOT include other entity-headers.
Otherwise (i.e., the conditional GET used a weak validator), the
response MUST NOT include other entity-headers; this prevents
inconsistencies between cached entity-bodies and updated headers.

If a 304 response indicates an entity not currently cached, then the
cache MUST disregard the response and repeat the request without the
conditional.

If a cache uses a received 304 response to update a cache entry, the
cache MUST update the entry to reflect any new field values given in
the response.

Chapitre 6: « Designing Read/Write Resource-Oriented Services »

Qui dit écriture dit ouverture d’un compte utilisateur qui devient une ressource avec les problèmes d’authentification et d’autorisation associés. Il faut utiliser le champ entête ‘Authorization


14.8 Authorization

A user agent that wishes to authenticate itself with a server-- usually, but not necessarily, after receiving a 401 response--does so by including an Authorization request-header field with the request. The Authorization field value consists of credentials containing the authentication information of the user agent for the realm of the resource being requested. Authorization = "Authorization" ":" credentials HTTP access authentication is described in "HTTP Authentication: Basic and Digest Access Authentication" [43]. If a request is authenticated and a realm specified, the same credentials SHOULD be valid for all other requests within this realm (assuming that the authentication scheme itself does not require otherwise, such as credentials that vary according to a challenge value or using synchronized clocks). When a shared cache (see section 13.7) receives a request containing an Authorization field, it MUST NOT return the corresponding response as a reply to any other request, unless one of the following specific exceptions holds: 1. If the response includes the "s-maxage" cache-control directive, the cache MAY use that response in replying to a subsequent request. But (if the specified maximum age has passed) a proxy cache MUST first revalidate it with the origin server, using the request-headers from the new request to allow the origin server to authenticate the new request. (This is the defined behavior for s-maxage.) If the response includes "s- maxage=0", the proxy MUST always revalidate it before re-using it. 2. If the response includes the "must-revalidate" cache-control directive, the cache MAY use that response in replying to a subsequent request. But if the response is stale, all caches MUST first revalidate it with the origin server, using the request-headers from the new request to allow the origin server to authenticate the new request. 3. If the response includes the "public" cache-control directive, it MAY be returned in reply to any subsequent request.

Si la réponse est 401 (« Unauthorized ») la réponse doit inclure champ entête ‘WWW-Authenticate‘.


10.4.2 401 Unauthorized

The request requires user authentication. The response MUST include a WWW-Authenticate header field (section 14.47) containing a challenge applicable to the requested resource. The client MAY repeat the request with a suitable Authorization header field (section 14.8). If the request already included Authorization credentials, then the 401 response indicates that authorization has been refused for those credentials. If the 401 response contains the same challenge as the prior response, and the user agent has already attempted authentication at least once, then the user SHOULD be presented the entity that was given in the response, since that entity might include relevant diagnostic information. HTTP access authentication is explained in "HTTP Authentication: Basic and Digest Access Authentication" [43].

Les principaux mécanismes d’authentification sont ‘HTTP basic, ‘HTTP Digest’ (http://tools.ietf.org/html/rfc2617, HTTP Authentication: Basic and Digest Access Authentication) et ‘WSSE’ qui sont très peu sécurisés. Voir chapitre 8 pour plus de détails.

Les auteurs parlent à nouveau de XHTML5 (http://www.whatwg.org/specs/web-apps/current-work/, HTML 5 Working Draft — 28 June 2007) qui permettra (quand ?) d’utiliser ‘PUT’ et ‘DELETE’ dans les formulaires. Ils parlent du nouvel attribut ‘template’ (pas encore approuvé , voir http://tools.ietf.org/id/draft-gregorio-uritemplate-00.txt )

   A URI Template is a sequence of characters that contains one or more
   embedded template variables Section 4.1.  A URI Template becomes a
   URI when the template variables are substituted with the template
   variables string values, see Section 4.2.  The following shows an
   example URI Template:

   http://example.com/widgets/widget_id

   If the value of the widget_id variable is "xyzzy", the resulting URI
   after substitution is:

   http://example.com/widgets/xyzzy

Chapitre 7: « A service implementation »

Les auteurs rappellent que jusqu’à présent les frameworks Web se sont focalisés sur les applications web pour les butineurs Web (web browser) et qu’ils n’utilisaient donc que les 2 seuls méthodes possibles GET et ‘POST’ (voir http://cafe.elharo.com/web/why-rest-failed/ et http://www.w3.org/TR/html401/interact/forms.html#adef-method).

De nouveaux frameworks pour développer des services RESTful sont apparus: Django (Python), Restlet (Java) et Ruby On Rails. (ces frameworks seront détaillés au chapitre 12)

Le but de ce chapitre est d’écrire une application de type ‘social bookmarking’ RESTful avec RubyOnRails. Alors allons-y !

pve@pc72 /cygdrive/e/projets
$ rails bookmarks
create
create app/controllers
create app/helpers
create app/models
create app/views/layouts
create config/environments
create components
create db
create doc
create lib
create lib/tasks
create log
create public/images
create public/javascripts
create public/stylesheets
create script/performance
create script/process
create test/fixtures
create test/functional
create test/integration
create test/mocks/developmen
create test/mocks/test
create test/unit
create vendor
create vendor/plugins
create tmp/sessions
create tmp/sockets
create tmp/cache
create tmp/pids
create Rakefile
create README
create app/controllers/appli
create app/helpers/applicati
create test/test_helper.rb
create config/database.yml
create config/routes.rb
create public/.htaccess
create config/boot.rb
create config/environment.rb
create config/environments/p
create config/environments/d
create config/environments/t
create script/about
create script/breakpointer
create script/console
create script/destroy
create script/generate
create script/performance/be
create script/performance/pr
create script/process/reaper
create script/process/spawne
create script/process/inspec
create script/runner
create script/server
create script/plugin
create public/dispatch.rb
create public/dispatch.cgi
create public/dispatch.fcgi
create public/404.html
create public/500.html
create public/index.html
create public/favicon.ico
create public/robots.txt
create public/images/rails.p
create public/javascripts/pr
create public/javascripts/ef
create public/javascripts/dr
create public/javascripts/co
create public/javascripts/ap
create doc/README_FOR_APP
create log/server.log
create log/production.log
create log/development.log
create log/test.log

pve@pc72 /cygdrive/e/projets

$ script/plugin discover
Add http://www.agilewebdevelopment.com/plugins/? [Y/n] Y
Add svn://rubyforge.org/var/svn/expressica/plugins/? [Y/n] Y
Add http://soen.ca/svn/projects/rails/plugins/? [Y/n] Y
Add http://technoweenie.stikipad.com/plugins/? [Y/n] Y
Add http://svn.techno-weenie.net/projects/plugins/? [Y/n] Y
Add http://svn.recentrambles.com/plugins/? [Y/n] Y
Add http://opensvn.csie.org/rails_file_column/plugins/? [Y/n] Y
Add http://svn.protocool.com/rails/plugins/? [Y/n] Y
Add http://tools.assembla.com/svn/breakout/breakout/vendor/plugins/? [Y/
Add http://svn.pragprog.com/Public/plugins/? [Y/n] Y
Add http://source.collectiveidea.com/public/rails/plugins/? [Y/n] Y
Add https://secure.near-time.com/svn/plugins/? [Y/n] Y
Add http://svn.inlet-media.de/svn/rails_extensions/plugins/? [Y/n] Y
Add http://svn.viney.net.nz/things/rails/plugins/? [Y/n] Y
Add http://svn.hasmanythrough.com/public/plugins/? [Y/n] Y
Add http://svn.shiftnetwork.com/plugins/? [Y/n] Y
Add svn://caboo.se/plugins/? [Y/n] Y
Add http://svn.6brand.com/projects/plugins/? [Y/n] Y
Add http://shanesbrain.net/svn/rails/plugins/? [Y/n] Y
Add svn://errtheblog.com/svn/plugins/? [Y/n] Y
Add http://svn.nkryptic.com/plugins/? [Y/n] Y
Add http://svn.thoughtbot.com/plugins/? [Y/n] Y
Add http://svn.webwideconsulting.com/plugins/? [Y/n] Y
Add http://invisible.ch/svn/projects/plugins/? [Y/n] Y
Add svn://rubyforge.org/var/svn/enum-column/plugins/? [Y/n] Y
Add http://streamlinedframework.org:8079/streamlined/plugins/? [Y/n] Y
Add svn://dvisionfactory.com/rails/plugins/? [Y/n] Y
Add http://hivelogic.com/plugins/? [Y/n] Y
Add http://mattmccray.com/svn/rails/plugins/? [Y/n] Y
Add svn://rubyforge.org/var/svn/cartographer/plugins/? [Y/n] Y
Add http://www.svn.recentrambles.com/plugins/? [Y/n] Y
Add http://tanjero.com/svn/plugins/? [Y/n] Y
Add http://filetofsole.org/svn/public/projects/rails/plugins/? [Y/n] Y
Add http://topfunky.net/svn/plugins/? [Y/n] Y
Add http://svn.joshpeek.com/projects/plugins/? [Y/n] Y
Add svn://rubyforge.org/var/svn/agtools/plugins/? [Y/n] Y
Add http://svn.aviditybytes.com/rails/plugins/? [Y/n] Y
Add http://beautifulpixel.textdriven.com/svn/plugins/? [Y/n] Y
Add http://mabs29.googlecode.com/svn/trunk/plugins/? [Y/n] Y
Add http://www.codyfauser.com/svn/projects/plugins/? [Y/n] Y
Add http://craz8.com/svn/trunk/plugins/? [Y/n] Y
Add http://sean.treadway.info/svn/plugins/? [Y/n] Y
Add http://svn.thebootstrapnation.com/public/plugins/? [Y/n] Y
Add http://www.mattmccray.com/svn/rails/plugins/? [Y/n] Y
Add svn://rubyforge.org//var/svn/validaterequest/plugins/? [Y/n] Y
Add http://sprocket.slackworks.com/svn/rails/plugins/? [Y/n] Y
Add http://svn.simpltry.com/plugins/? [Y/n] Y
Add http://svn.elctech.com/svn/public/plugins/? [Y/n] Y
Add http://xmlblog.stikipad.com/plugins/? [Y/n] Y
Add http://www.xml-blog.com/svn/plugins/? [Y/n] Y
Add http://svn.toolbocks.com/plugins/? [Y/n] Y
Add http://thar.be/svn/projects/plugins/? [Y/n] Y
Add http://code.teytek.com/rails/plugins/? [Y/n] Y
Add http://www.infused.org/svn/plugins/? [Y/n] Y
Add svn://rubyforge.org/var/svn/apptrain/trunk/vendor/plugins/? [Y/n] Y
Add http://s3cachestore.googlecode.com/svn/trunk/plugins/? [Y/n] Y
Add http://sbecker.net/shared/plugins/? [Y/n] Y
Add http://opensvn.csie.org/macaque/plugins/? [Y/n] Y
Add http://svn.designbyfront.com/rails/plugins/? [Y/n] Y
Add http://svn.rails-engines.org/plugins/? [Y/n] Y
Add http://dev.fiatdev.com/svn/plugins/? [Y/n] Y
Add http://john.guen.in/svn/plugins/? [Y/n] Y
Add http://www.redhillonrails.org/svn/trunk/vendor/plugins/? [Y/n] Y
Add svn://rubyforge.org/var/svn/actsdisjoint/plugins/? [Y/n] Y
Add http://ajaxmessaging.googlecode.com/svn/trunk/plugins/? [Y/n] Y
Add http://mod-i18n.googlecode.com/svn/trunk/plugins/? [Y/n] Y

$ script/plugin install acts_as_taggable
svn: Can’t connect to host ‘rubyforge.org’: Connect
svn: Can’t connect to host ‘caboo.se’: Connection t
svn: Can’t connect to host ‘errtheblog.com’: Connec
svn: Can’t connect to host ‘rubyforge.org’: Connect
svn: Can’t connect to host ‘dvisionfactory.com’: Co
svn: Can’t connect to host ‘rubyforge.org’: Connect
+ ./acts_as_taggable/MIT-LICENSE
+ ./acts_as_taggable/README
+ ./acts_as_taggable/generators/acts_as_taggable_ta
generator.rb
+ ./acts_as_taggable/generators/acts_as_taggable_ta
+ ./acts_as_taggable/init.rb
+ ./acts_as_taggable/lib/acts_as_taggable.rb
+ ./acts_as_taggable/lib/tag.rb
+ ./acts_as_taggable/lib/tagging.rb
+ ./acts_as_taggable/tasks/acts_as_taggable_tasks.r
+ ./acts_as_taggable/test/acts_as_taggable_test.rb

$ script/plugin install http_authentication
svn: Can’t connect to host ‘rubyforge.org’:
svn: Can’t connect to host ‘caboo.se’: Conn
svn: Can’t connect to host ‘errtheblog.com’
svn: Can’t connect to host ‘rubyforge.org’:
svn: Can’t connect to host ‘dvisionfactory.
svn: Can’t connect to host ‘rubyforge.org’:
svn: Can’t connect to host ‘rubyforge.org’:
svn: Can’t connect to host ‘rubyforge.org’:
svn: Can’t connect to host ‘rubyforge.org’:
svn: Can’t connect to host ‘rubyforge.org’:
Plugin not found: [« http_authentication »]

Chapitre 8: « REST and ROA Best Practices »

Une récapitulation des bonnes pratiques.

Chapitre 9: « The building Blocks of Services »

Pour rappeler que les services Web sont basés sur 3 technologies fondamentales: HTTP, URIs et XML.

Les auteurs nous parlent des formats de représentation tels que XHTML (mime-type: application/xhtml+xml), les microformats, Atom, OpenSearch, SVG, form-encode Key-Value Pairs (application/x-www-form-urlencode), JSON, RDF, RDFa.

On nous parle de l’encodage de caractères . Aux Etats Unis, on utilise UTF-8, US-ASCII ou Windows 1252. En Europe on utilise l’ISO-8859-1. Au Japon on utilise EUC-JP, Shift-JS ou UTF-8.

L’utilisation de la norme Unicode permet de mettre de l’ordre dans l’utilisation de tous ces différents codages en utilisant 2 formes de transformation universelle que sont UTF-8 et UTF-16 (pour les langues asiatiques).

Il existe un excellent détecteur d’encode universal écrit en python (http://chardet.feedparser.org)

 

>>> import urllib
>>> urlread = lambda url: urllib.urlopen(url).read()
>>> import chardet
>>> chardet.detect(urlread("http://google.cn/"))
{'encoding': 'GB2312', 'confidence': 0.99}

>>> chardet.detect(urlread("http://yahoo.co.jp/"))
{'encoding': 'EUC-JP', 'confidence': 0.99}

>>> chardet.detect(urlread("http://amazon.co.jp/"))
{'encoding': 'SHIFT_JIS', 'confidence': 1}

>>> chardet.detect(urlread("http://pravda.ru/"))
{'encoding': 'windows-1251', 'confidence': 0.9355}

>>> chardet.detect(urlread("http://auction.co.kr/"))
{'encoding': 'EUC-KR', 'confidence': 0.99}

>>> chardet.detect(urlread("http://haaretz.co.il/"))
{'encoding': 'windows-1255', 'confidence': 0.99}

>>> chardet.detect(urlread("http://www.nectec.or.th/tindex.html"))
{'encoding': 'TIS-620', 'confidence': 0.7675}

>>> chardet.detect(urlread("http://feedparser.org/docs/"))
{'encoding': 'utf-8', 'confidence': 0.99}


Copyright © 2006 Mark Pilgrim · mark@diveintomark.org · Terms of use

XML permet de dire au client quel encodage on a utilisé en le spécifiant sur la première ligne du fichier XML:

<?xml version= »1.0″ encoding= »UTF-8″?>

HTTP avec son attribut d’entête Content-Type peut indiquer également l’encodage utilisé et il est préférable que cela soit le même que le document XML transmis. Si il est différent c’est le codage défini pat Content-Type qui prime. Ceci est un piège !


14.17 Content-Type

The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET. Content-Type = "Content-Type" ":" media-type Media types are defined in section 3.7. An example of the field is Content-Type: text/html; charset=ISO-8859-4 Further discussion of methods for identifying the media type of an entity is provided in section 7.2.1.

Pour ces problèmes voir http://tools.ietf.org/html/rfc3023 (XML Media Types) et l’article de Mark Pilgrim « XML on the Web Has Failed » http://www.xml.com/pub/a/2004/07/21/dive.html

Description des protocoles:

APP , http://tools.ietf.org/wg/atompub/ .

– GData qui est une extension de APP (http://code.google.com/apis/gdata/clientlibs.html). Les applications Blogger, Google Calendar, Google code search et Google spreadsheet exposent toutes des services web RESTful avec la même interface : le Protocole de Publication Atom (APP) avec les extensions GData.

Les auteurs parlent ensuite de ‘POE’ (Post Once Exactly, http://www.mnot.net/drafts/draft-nottingham-http-poe-00.txt ), des URI templates, de XHTML4 et de ses nombreuses limitations.

Pour XHTML5 le problème est sa date d’adoption: de fin 2008 à 2022 pour les plus réalistes :(. Voir http://blog.welldesignedurls.org)

Je passe sur WADL.

Chapitre 10 : The Resource-Oriented Architecture Versus Big Web Services

Bon ce sont toutes les technologies SOAP, WSDL WS-: je passe.

Chapitre 11: Ajax applications as REST clients

Pour les auteurs une application AJAX est un service web client qui tourne à l’intérieur d’un butineur (web browser)

Gmail est un service web et il existe une bibliothèque d’accès à ce service: http://libgmail.sourceforge.net (http://libgmail.sourceforge.net/, « Python binding for Google’s Gmail service »).

AJAX est devenu Ajax car pour les auteurs Ajax est un style d’architecture qui n’a pas nécessairement besoin ni de Javascript(on peut utiliserActionScript, Java, VBScript, python) ni de XML (on peut utiliser JSON, du HTML, du texte).

Presque tous les butineurs fournissent un objet javascript XMLHttpRequest avec les 5 méthodes HTTP de base: GET, HEAD, POST, PUT et DELETE avec la possibilité de modifier l’entête et le corps d’une requête HTTP. Un site pour tester son navigateur: http://mnot.net/javascript/xmlhttprequest/

Etant donné les différences d’implémentation de Javascript il est fortement conseillé d’employer des bibliothèques.

Bibliothèques utilisées pour Javascript:

Prototype : Attention: on ne peut pas modifier les champs d’entête !

Dojo

Pour plus d’informations sur les biblothèques Javascript voir http://en.wikipedia.org/wiki/Category:JavaScript_libraries . La bibliothèque Javascript qui monte est la bibliothèque jQuery voir http://docs.jquery.com/Sites_Using_jQuery

Je passe sur JoD (Javascript on Demand)

Chapitre 12 : Frameworks for RESTful Services

Dans ce dernier chapitre, les auteurs passent en revue 3 frameworks REStful: Ruby On rails, Restlet (Java) et Django (Python).

Ruby On Rails:

doit son succès au fait de respecter des conventions. La version 1.2 a une conception RESTful

Restlet

Restlet a été influencé par les technologies majeures de Java: l’API Servlet, les Java Server Pages , HTTPUrlConnection et Struts .

Voir Retrotranslator (http://retrotranslator.sourceforge.net/#what)

Django

La conception de Django est similaire à celle de Rails bien qu’ils fassent moins de simplifications.

Installation:

# extraction des sources django
$ svn co http://code.djangoproject.com/svn/django/trunk/ ~/django_src

$ python -c « from distutils.sysconfig import get_python_lib; print get_python_lib() »
/usr/lib/python2.5/site-packages

$ ln -s /cygdrive/h/django_src/django /usr/lib/python2.5/site-packages/django

# on met django-admin.py dans le chemin PATH

$ ln -s ~/django_src/django/bin/django-admin.py /usr/local/bin

pve@pc72 ~/django_src
$ which django-admin.py
/usr/local/bin/django-admin.py

// Le lendemain ==> mise à jour de django

$ cd ~/django_src; svn update
U django/test/client.py
U django/contrib/auth/__init__.py
U tests/modeltests/test_client/fixtures/testdata.json
U tests/modeltests/test_client/models.py
Updated to revision 5678.

# installation du projet django: voir http://www.djangoproject.com/documentation/tutorial01/

cd /cygdrive/e/projets/

Writing your first Django app, part 1 (http://www.djangoproject.com/documentation/tutorial01/)

Création du projet pybookmarks

$ date; django-admin.py startproject pybookmarks; date
Fri Jul 13 09:03:02 2007
Fri Jul 13 09:03:04 2007

pve@pc72 /cygdrive/e/projets
$ ls -als pybookmarks/
total 48
0 drwxr-xr-x 2 pve mkgroup-l-d 0 Jul 13 09:03 .
0 drwxr-xr-x 6 pve mkgroup-l-d 0 May 10 11:19 ..
0 -rw-r–r– 1 pve mkgroup-l-d 0 Jul 13 09:03 __init__.py
16 -rwxr-xr-x 1 pve mkgroup-l-d 546 Jul 13 09:03 manage.py
16 -rw-r–r– 1 pve mkgroup-l-d 2933 Jul 13 09:03 settings.py
16 -rw-r–r– 1 pve mkgroup-l-d 235 Jul 13 09:03 urls.py

pve@pc72 /cygdrive/e/projets/pybookmarks
$ python manage.py runserver
Validating models…
0 errors found.

Django version 0.97-pre, using settings ‘pybookmarks.settings’
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

Projet django initial

voir:Pour la base de données j’ai dû choisir le site “ftp://sunsite.dk/projects/cygwinports” pour pouvoir installer la base de données sqlite3. Pour vérifier que la base sqlite3 est opérationnelle je fais:

$ python
Python 2.5.1 (r251:54863, Jun 19 2007, 22:55:07)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type « help », « copyright », « credits » or « license » for more information.
>>> import sqlite3
>>>

Modication du fichier /cygdrive/e/projets/pybookmarks/settings.py

modification du fichier applicatif setting.py

 pve@pc72 /cygdrive/e/projets/pybookmarks
$ python manage.py syncdb
Creating table auth_message
Creating table auth_group
Creating table auth_user
Creating table auth_permission
Creating table django_content_type
Creating table django_session
Creating table django_site

You just installed Django’s auth system, which means you don’t have any superuse
rs defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use ‘pve’):
E-mail address: pvergain@gmail.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Message model
Installing index for auth.Permission model
Loading ‘initial_data’ fixtures…
No fixtures found.

# Création de notre application
$ date; python manage.py startapp bookmarks; date
Fri Jul 13 13:03:58     2007
Fri Jul 13 13:04:00     2007

pve@pc72 /cygdrive/e/projets/pybookmarks
$ ls -als bookmarks/
total 32
0 drwxr-xr-x 2 pve mkgroup-l-d  0 Jul 13 13:04 .
0 drwxr-xr-x 3 pve mkgroup-l-d  0 Jul 13 09:03 ..
0 -rw-r–r– 1 pve mkgroup-l-d  0 Jul 13 13:04 __init__.py
16 -rw-r–r– 1 pve mkgroup-l-d 57 Jul 13 13:04 models.py
16 -rw-r–r– 1 pve mkgroup-l-d 26 Jul 13 13:04 views.py

Modification du modèle de données (models.py)


     Le modèle de données

ATTENTION: ne pas oublier le codage dans l’entête du fichier + la méthode __unicode__ non décrite dans le bouquin !

#!/usr/bin/python
# -*- coding: UTF-8 -*-

pve@pc72 /cygdrive/e/projets/pybookmarks
$ python manage.py sql bookmarks
BEGIN;
CREATE TABLE « bookmarks_bookmark » (
« id » integer NOT NULL PRIMARY KEY,
« user_id » integer NOT NULL,
« url » varchar(200) NOT NULL,
« short_description » varchar(255) NOT NULL,
« long_description » text NOT NULL,
« timestamp » datetime NOT NULL,
« public » bool NOT NULL
)
;
CREATE TABLE « bookmarks_tag » (
« id » integer NOT NULL PRIMARY KEY,
« name » varchar(100) NOT NULL
)
;
CREATE TABLE « bookmarks_bookmark_tags » (
« id » integer NOT NULL PRIMARY KEY,
« bookmark_id » integer NOT NULL REFERENCES « bookmarks_bookmark » (« id »),
« tag_id » integer NOT NULL REFERENCES « bookmarks_tag » (« id »),
UNIQUE (« bookmark_id », « tag_id »)
)
;
COMMIT;

If you’re interested, also run the following commands:
  • python manage.py validate pybookmarks — Checks for any errors in the construction of your models.
  • python manage.py sqlcustom pybookmarks — Outputs any custom SQL statements (such as table modifications or constraints) that are defined for the application.
  • python manage.py sqlclear pybookmarks — Outputs the necessary DROP TABLE statements for this app, according to which tables already exist in your database (if any).
  • python manage.py sqlindexes pybookmarks — Outputs the CREATE INDEX statements for this app.
  • python manage.py sqlall pybookmarks — A combination of all the SQL from the ‘sql’, ‘sqlcustom’, and ‘sqlindexes’ commands.

Looking at the output of those commands can help you understand what’s actually happening under the hood.

Looking at the output of those commands can help you understand what’s actually happening under the hood.

$ python manage.py syncdb
Creating table auth_message
Creating table auth_group
Creating table auth_user
Creating table auth_permission
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table bookmarks_bookmark
Creating table bookmarks_tag

You just installed Django’s auth system, which mean
rs defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use ‘pve’):
E-mail address: pvergain@gmail.com
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Message model
Installing index for auth.Permission model
Installing index for bookmarks.Bookmark model
Installing index for bookmarks.Tag model
Loading ‘initial_data’ fixtures…
No fixtures found.

Writing your first Django app, part 2 (http://www.djangoproject.com/documentation/tutorial02/)

Generating admin sites for your staff or clients to add, change and delete content is tedious work that doesn’t require much creativity. For that reason, Django entirely automates creation of admin interfaces for models.

Django was written in a newsroom environment, with a very clear separation between “content publishers” and the “public” site. Site managers use the system to add news stories, events, sports scores, etc., and that content is displayed on the public site. Django solves the problem of creating a unified interface for site administrators to edit content.

The admin isn’t necessarily intended to be used by site visitors; it’s for site managers.

Add "django.contrib.admin" to your INSTALLED_APPS setting.

INSTALLED_APPS = (
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.sites’,
‘pybookmarks.bookmarks’,
‘django.contrib.admin’,
)

Run python manage.py syncdb. Since you have added a new application to INSTALLED_APPS, the database tables need to be updated.

$ python manage.py syncdb
Creating table django_admin_log
Installing index for admin.LogEntry model
Loading ‘initial_data’ fixtures…
No fixtures found.

Edit your mysite/urls.py file and uncomment the line below “Uncomment this for admin:”. This file is a URLconf; we’ll dig into URLconfs in the next tutorial. For now, all you need to know is that it maps URL roots to applications.

Recall from Tutorial 1 that you start the development server like so:

python manage.py runserver

Now, open a Web browser and go to “/admin/” on your local domain — e.g., http://127.0.0.1:8000/admin/. You should see the admin’s login screen:

Administration django

 

Just one thing to do: We need to specify in the bookmarks model that Bookmark objects have an admin interface. Edit the pybookmarks/bookmarks/models.py file and make the following change to add an inner Admin class:

The class Admin will contain all the settings that control how this model appears in the Django admin. All the settings are optional, however, so creating an empty class means “give this object an admin interface using all the default options.

Now reload the Django admin page to see your changes. Note that you don’t have to restart the development server — the server will auto-reload your project, so any modifications code will be seen immediately in your browser.

 Et ça marche !

 Admin bookmarks

Saisie d’un bookmark

Things to note here:

  • The form is automatically generated from the Poll model.
  • The different model field types (models.DateTimeField, models.CharField) correspond to the appropriate HTML input widget. Each type of field knows how to display itself in the Django admin.
  • Each DateTimeField gets free JavaScript shortcuts. Dates get a “Today” shortcut and calendar popup, and times get a “Now” shortcut and a convenient popup that lists commonly entered times.

Writing your first Django app, part 3 (http://www.djangoproject.com/documentation/tutorial03/)

Installation de dateutil: d’abord le télécharger, le décompresser, aller sous le répertoire python-dateutil et faire ‘python setup.py install’

$ python setup.py install
running install
running build
running build_py
creating build
creating build/lib
creating build/lib/dateutil
copying dateutil/__init__.py -> build/lib/dateutil
copying dateutil/easter.py -> build/lib/dateutil
copying dateutil/parser.py -> build/lib/dateutil
copying dateutil/relativedelta.py -> build/lib/dateutil
copying dateutil/rrule.py -> build/lib/dateutil
copying dateutil/tz.py -> build/lib/dateutil
copying dateutil/tzwin.py -> build/lib/dateutil
creating build/lib/dateutil/zoneinfo
copying dateutil/zoneinfo/__init__.py -> build/lib/dateutil/zoneinfo
running install_lib
creating /usr/lib/python2.5/site-packages/dateutil
copying build/lib/dateutil/__init__.py -> /usr/lib/python2.5/site-packages/dateutil
copying build/lib/dateutil/easter.py ->/usr/lib/python2.5/site-packages/dateutil
copying build/lib/dateutil/parser.py -> /usr/lib/python2.5/site-packages/dateutil
copying build/lib/dateutil/relativedelta.py -> /usr/lib/python2.5/site-packages/dateutil
copying build/lib/dateutil/rrule.py -> /usr/lib/python2.5/site-packages/dateutil

copying build/lib/dateutil/tz.py -> /usr/lib/python2.5/site-packages/dateutil
copying build/lib/dateutil/tzwin.py -> /usr/lib/python2.5/site-packages/dateutil

creating /usr/lib/python2.5/site-packages/dateutil/zoneinfo
copying build/lib/dateutil/zoneinfo/__init__.py -> /usr/lib/python2.5/site-packages/dateutil/zoneinfo
byte-compiling /usr/lib/python2.5/site-packages/dateutil/__init__.py to __init__
.pyc
byte-compiling /usr/lib/python2.5/site-packages/dateutil/easter.py to easter.pyc
byte-compiling /usr/lib/python2.5/site-packages/dateutil/parser.py to parser.pyc
byte-compiling /usr/lib/python2.5/site-packages/dateutil/relativedelta.py to relativedelta.pyc
byte-compiling /usr/lib/python2.5/site-packages/dateutil/rrule.py to rrule.pyc
byte-compiling /usr/lib/python2.5/site-packages/dateutil/tz.py to tz.pyc
byte-compiling /usr/lib/python2.5/site-packages/dateutil/tzwin.py to tzwin.pyc
byte-compiling /usr/lib/python2.5/site-packages/dateutil/zoneinfo/__init__.py to
__init__.pyc
running install_data
copying dateutil/zoneinfo/zoneinfo-2007f.tar.gz -> /usr/lib/python2.5/site-packages/dateutil/zoneinfo
running install_egg_info
Writing /usr/lib/python2.5/site-packages/python_dateutil-1.2-py2.5.egg-info

# On vérifie que ça marche
$ python
Python 2.5.1 (r251:54863, Jun 19 2007, 22:55:07)
[GCC 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)] on cygwin
Type « help », « copyright », « credits » or « license » for more information.

>>> import dateutil.parser
>>>
La suite la semaine prochaine.

http://www.djangosites.org/latest/

http://www.djangobook.com/

http://www.djangoproject.com/

Posted in Architecture logicielle, http, python, REST, ruby, URI, Web applications, XHTML5, XML | Leave a Comment »

Architecture logicielle web avec Ajax/REST, HTTP

Posted by patrick sur février 6, 2007

Source: http://www-128.ibm.com/developerworks/xml/library/wa-ajaxarch/

J’ai découvert l’architecture REST en lisant l’excellent livre de Christophe Porteneuve « Bien développer pour le Web 2.0 ». Je continue d’approfondir mes connaissances sur ce sujet en lisant cet article.

Immersive Web applications are certainly useful, but the server-side immersive Web application style is in fundamental disharmony with REST architectural principles. Specifically, it violates a key REST constraint and fails to take advantage of one of REST’s most important advantages, thereby spawning a new set of problems. REST’s « client-stateless-server » constraint forbids session state on the server. Designing within this constraint promotes the system properties of visibility, reliability, and scalability. But immersive server-side Web applications wish to provide a great deal of personalization to a single user, so they must choose between two designs. The first is to send a massive amount of state information with each client request, so that each request is context-complete and the server can remain stateless. A second, ostensibly simpler, solution favored by application developers and middleware vendors alike is to send a simple user identity token and associate this token with a « user session » object on the server side. The second design directly violates the client-stateless-server constraint. It certainly enables desirable user functionality (especially personalization), but it places tremendous strain on the architecture. ava™ Servlet’s HttpSession API provides an example of this strain. HttpSession lets you associate session state with a particular user. This API seems deceptively simple to novice developers. Indeed, it appears that you can store any object in HttpSession and pull it out without ever coding any special lookup logic yourself. But as you start putting more objects in HttpSession, you start to notice that your application server uses more and more memory and processing resources. Soon you decide that you need to deploy your application in a clustered environment to help with growing resource needs. Then you realize that for HttpSession to work in a clustered environment, each object must implement Java’s Serializable interface so that session data can be transmitted between servers in a clustered environment. Then you must decide whether or not your application server should persist session data in the case of a shutdown/restart cycle. Soon you begin to question whether violating the client-stateless-server constraint was such a good idea after all. (Actually, many developers are ignorant of this constraint.)

But why centralize so much resource consumption on an overburdened server, when in theory you could distribute processing and memory needs to clients? The simple answer is that given traditional Web browser constraints, this wasn’t feasible (see Client-side processing without Ajax). But the Ajax architectural style lets developers distribute processing and state requirements to the client. Read on to learn why immersive applications that choose an Ajax-style architecture can regain harmony with REST and enjoy its benefits.

….

The Dojo Toolkit is a good example (see Resources). Dojo provides build-time tools to create a compressed JavaScript file containing all of your application’s logic, presentation, and styles. Because it’s ultimately just a file, a Web browser can cache it, meaning that the second time you visit a Dojo-enabled Web application, you’re likely loading the Ajax engine from your browser’s cache rather than from the server. Compare this to a highly immersive server-side Web application where every request results in significant server processing because your browser and network intermediaries can’t cache the ever-changing resources.

….

What about the business data? Because the application logic and state reside and execute on the browser, the application’s interaction with the server becomes very different from that of a traditional Web application. Instead of fetching amalgamated pages of content, it simply needs to fetch business data.

Another benefit of the Ajax architectural style is the ability to deal easily with server failure. As I mentioned before, server-side Web applications with immersive user experiences tend to hold large amounts of user session state on the server. If a server fails, the session state goes away and users experience odd browser behavior (« Why am I back to the home page? And where are the items in my shopping cart? »). In an Ajax application with a stateful client and stateless services, a server crash/restart can be completely transparent to the user because the server crash can’t affect session state, which lives in the user’s browser; a stateless service’s behavior is idempotent and determined solely by the content of user requests.

Rappel (http://fr.wikipedia.org/wiki/REST) :
REST (Representational state transfer) est une manière de construire une application pour les systèmes distribués comme le World Wide Web. Le terme a été inventé par Roy Fielding.

REST n’est pas un protocole ou un format, c’est une architecture, c’est l’architecture originale du Web, bâtie sur quelques principes simples :

  • l’URI est important : connaître l’URI doit suffire pour accéder à la ressource;
  • HTTP fournit toutes les opérations nécessaires (GET, POST, PUT et DELETE, essentiellement);
  • chaque opération est auto-suffisante : il n’y a pas d’état;
  • utilisation des standards hypermedia : HTML ou XML qui permettent de faire des liens vers d’autres ressources et d’assurer ainsi la navigation dans l’application REST.

Cette architecture n’est pas limitée à la réalisation d’application pour un utilisateur humain. Elle est de plus en plus utilisée pour la réalisation de services Web destinés à la communication entre machines. Dans ce cadre là, les requêtes et les réponses sont typiquement encodées en XML. REST dans ce cas là se pose en alternative à RPC et SOAP, alternative censée être plus simple à mettre en œuvre. Les systèmes qui suivent les principes REST de Fielding sont souvent appelés RESTful.

La thèse de Roy Fielding précise les avantages de cette architecture par rapport à d’autres architectures d’applications web. Citons entres autres :

  • L’absence d’état sur le serveur conduit à une consommation de mémoire inférieure et donc à une capacité plus grande de répondre à un grand nombre de requêtes simultanées.
  • L’absence d’état sur le serveur rend le fonctionnement plus simple à appréhender. Le résultat d’une requête ne dépend pas de variables cachées difficilement identifiables. Cela conduit à une mise au point plus simple.
  • L’absence d’état serveur permet une répartition des requêtes sur plusieurs serveurs avec une meilleure granularité et de manière plus souple. Cela permet aussi une meilleure tolérance aux pannes d’un des serveurs.
  • Le respect de la philosophie du protocole HTTP, à la différence de SOAP conduit à une architecture plus cohérente et plus simple.
  • l’utilisation d’URI comme représentant d’une ressource, permet la mise en place de serveurs cache.

http://tools.ietf.org/html/rfc2616  (« 9 Method Definitions ……………………………………..51

   9.1   Safe and Idempotent Methods .................................51
   9.1.1    Safe Methods .............................................51
   9.1.2    Idempotent Methods .......................................51
   9.2   OPTIONS .....................................................52
   9.3   GET .........................................................53
   9.4   HEAD ........................................................54
   9.5   POST ........................................................54
   9.6   PUT .........................................................55
   9.7   DELETE ......................................................56
   9.8   TRACE .......................................................56
   9.9   CONNECT .....................................................57)")

Posted in Architecture logicielle, http, javascript, REST | Leave a Comment »