Écrire des microservices en Python – 3

Dans Cette troisième partie Nous commencerons à explorer Tornado et à écrire des microservices, sans oublier un petit peu de théorie.

La base du choix de Tornado dérive d’une série de trois articles d’articles écrit par Bill Ward sur DZONE. Nous avons élargi considérablement l’exemple.

Les ressources web ont été définies pour la première fois sur le World Wide Web comme des documents ou des fichiers identifiés par leur URL (Uniform Resource Locator).

Dans un service web REST, les requêtes effectuées sur l’URL d’une ressource produisent une réponse dont le corps est formaté en HTML, XML, JSON ou un autre format. La réponse peut confirmer que la ressource stockée a été altérée et elle peut fournir des liens hypertextes vers d’autres ressources ou collection de ressources liées. Lorsque le protocole HTTP est utilisé, comme c’est souvent le cas, les méthodes HTTP disponibles sont GET, HEAD, POST, PUT, PATCH, DELETE, CONNECT, OPTIONS et TRACE… …(et encore plus).

Si les types des requêtes son très clairement specifiées, les réponses (ou mieux, les codes des réponses) le sont aussi, voir https://developer.mozilla.org/en-US/docs/Web/HTTP/Status. Pour le contenu, comme nous avons dit avant, nous avons le choix.

On passe à l’action. Pour le moment on se concentre sur Tornado.web et sur comment implémenter un petit service qui répond à des simple requêtes « GET », chose qui est vraiment simple!

On installe Tornado.web avec pip: « pip install tornado », sous Linux, sous MS Windows ça devient « python -m pip install tornado ».

Dans notre IDE ou éditeur préféré, nous reprenons l’exemple initial (le classique « Hello World » de la doc de Tornado :

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

application = tornado.web.Application([
    (r"/", MainHandler),
])

if __name__ == "__main__":
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

Le clés pour comprendre comment ça fonctionne :

  1. Comprendre tornado.web.RequestHandler
  2. Comprendre application = tornado.web.Application([(r”/”, MainHandler),])
  3. Comprendre application.listen(8888)
  4. Comprendre tornado.ioloop.IOLoop.instance().start()

La classe tornado.web.RequestHandler constitue le point de démarrage. Nous définissons de quelle façon une requête qui «arrive» dans notre site est traitée. Dans ce cas, nous étendons la classe de base, en créant une classe MainHandler. Cette classe, traitera les requêtes de type « GET » (pour lire des donées) en écrivant (self.write) « Hello World ».

Mais comment nous savons « où » faire pointer notre Browser web ou notre application « client » ? Nous trouvons la réponse dans la définition de notre application : application = tornado.web.Application([(r”/”, MainHandler),]). Si quelqu’un arrive dans notre site, à l’adresse principale, http:<site>/ il recevra en retour « Hello World ». Mais comment nous démarrons le service et qu’est que c’est <site>.

La réponse encore un fois vient de la ligne application.listen(8888). C’est à dire que nous definissons localhost et la porte 8888 comme point d’entrée de notre application web.La dernière ligne, tornado.ioloop.IOLoop.instance().start(), démarre la boucle du service web, qui est désormais à l’écoute sur l’adresse : http://localhost:8888/

Dernier sujet à discuter : Comment déboguer une application web comme celle très minimale qu’on viens d’écrire ? Il y a plusieurs solutions :

  • Fichiers de log
  • Débogage pas-a-pas (nécessite d’un IDE qui le supporte), pour analyser le comportement de notre application
  • Utilisation d’une application spécifique comme Postman, qui permet de fabriquer des requêtes à la main, d’explorer les réponses, d’automatiser des tests etc.
  • Utilisation d’un plugin pour navigateur web comme RESTer, disponible pour Firefox et Chrome et bien capable mais moins puissant de Postman

Il n’y a pas des recettes magiques, sauf peut-être essayer d’être très claires des le début sur la décomposition et les rôles de nos objets et de nos apis.

La suite au prochain chapitre…