-
Notifications
You must be signed in to change notification settings - Fork 3
/
express-framework-web-node.html
429 lines (130 loc) · 21.6 KB
/
express-framework-web-node.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
<!--config
Title: "Express: Le framework web Node qu'il fait bon utiliser"
Author: Mickael Daniel
Date: Dec 5 2010 15:27:00 GMT-0500 (CDT)
Note: This post is an import from an older wordpress post, as a results not markdown formated
Categories: javascript, node
config-->
<img class="mk-blog-img" src="{{site.baseurl}}assets/img/express/express-screen.png" />
<p>Quatrième article consacré à cette série node.js et au développement d’une petite application, celui-ci s'évertuera à vous présenter <a href="http://expressjs.com/">Express.js</a>. Express est un framework de développement web, inspiré par [Sinatra](http://www.sinatrarb.com/), proposant plusieurs fonctionnalités comme un système de vues (templates) très intuitif, un robuste système de routage, un exécutable pour générer des applications et bien plus encore.</p>
<p>Dans la perspective de cet article et histoire de me donner du grain à moudre, j'ai travaillé une petite application mettant en oeuvre Express et l'<a href="http://develop.github.com/">API Rest Github</a>. Le but, tout bête, étant de récupérer pour un repository donné tous les fichiers de type markdown (extension .md ou .markdown) et de les transmettre à l'utilisateur au format HTML. L'interface et les fonctionnalités seront très limitées, une simple liste des fichiers et la possibilité pour chacun d'eux de récupérer son contenu. Ceci pouvant constituer le point de départ d'un moteur de blog, agrégation de documentations et plus encore.</p>
<!--more-->
<h2>Express</h2>
<p>Bien qu'il existe d'autre alternative à Express dans la communauté Node (<a href="https://github.com/ry/node/wiki/modules#web-frameworks-full">liste non exhaustive</a>), express s'impose petit à petit comme le framework web de référence avec aujourd'hui plus de 1500 watchers (githuber suivant les modifications du repository).</p>
<img class="mk-blog-img-center" src="{{site.baseurl}}assets/img/express/express-watched.png" title="GitHub watched repos" alt="GitHub watched repos">
<p>Il repose sur <a href="https://github.com/senchalabs/connect">Connect</a>, <a href="http://howtonode.org/connect-it">un système à la Rack</a> pour nous épauler en nous offrant une <a href="http://senchalabs.github.com/connect/">bibliothèque impressionnante</a> et de grande qualité de couches middleware pour nos applications et modules Node. Il se trouve que le développeur principal d'Express est aussi un contributeur de Connect. Et si cela peut contribuer à asseoir la crédibilité de ces deux projets, une petite organisation du nom de <a href="https://github.com/senchalabs">Sencha</a> est derrière tout ça... Vous connaissez?</p>
<h3>Installation</h3>
<p>Concernant l'installation, <a href="http://expressjs.com/guide.html#Installation">plusieurs choix</a> s'offrent à vous: <a href="https://github.com/isaacs/npm">npm</a>, curl ou git clone/submodule udpate.</p>
<p>Nous choisirons la technique <a href="https://github.com/robrighter/node-boilerplate">node-boilerplate</a> (histoire de choisir une autre méthode! Pas vraiment, il s'agit essentiellement de l'utilisation de git et support des submodules) comme décrit dans <a href="http://blog.mklog.fr/2010/11/node-boilerplate/">l'article précédent</a>.</p>
<p>Dans la lignée de node-boilerplate, un <a href="http://twitter.com/#!/dalmaer/status/10941590767935488">tweet de Dion Almaer</a> m'a fait découvrir un nouveau venu qui risque de faire parler de lui: <a href="https://github.com/datapimp/backbone-express-mongoose-socketio">backbone-express-mongoose-socketio</a>. Un squelette d'application qui utilise <a href="http://expressjs.com">express</a>, <a href="http://socket.io">socket.io</a>, <a href="http://github.com/LearnBoost/mongoose">mongoose</a> & <a href="http://www.mongodb.org/">mongodb</a>, <a href="http://code.google.com/p/redis/">redis</a>, <a href="http://html5boilerplate.com/">html5 boilerplate</a> et <a href="http://github.com/documentcloud/backbone">backbone.js</a>.</p>
<h3>Le serveur</h3>
<p>Comme indiqué dans la <a href="http://expressjs.com/guide.html#Creating-An-Application">documentation officielle</a> d'Express, la mise en place d'un serveur est très simple et ressemble beaucoup à ce qu'on ferait avec l'API native de Node:</p>
<script src="https://gist.github.com/728415.js"> </script>
<h3>Configuration</h3>
<p>Express utilisant Connect, de nombreux composants et couches middleware se trouvent à notre disposition. Certaines préoccupations communes et courantes des applis web peuvent être difficile et coûteuse à implémenter (gestion des fichiers statiques, cookie/session, gestion des erreurs, etc.). Tout ceci est géré pour nous par Connect et Express.</p>
<p><em><strong>Example de configuration tiré de la <a href="http://expressjs.com/guide.html#Configuration">doc Express</a></strong></em></p>
<script src="https://gist.github.com/728436.js"> </script>
<p><em><strong>Si nous utilisons node-boilerplate pour générer notre application</strong></em></p>
<script src="https://gist.github.com/728438.js"> </script>
<p>Vous remarquerez une légère différence entre les deux versions. La première utilisant l'API d'Express pour accéder aux modules Connect, la seconde utilisant directement Connect. Le résultat étant sensiblement le même et s'explique par cette extrait du fichier index.js (celui décrivant le module Express et l'exportant):</p>
<p><em><strong>Export des middleware Connect</strong></em></p>
<script src="https://gist.github.com/728448.js"> </script>
<p>La configuration d'un module aussi diffère entre ces deux extraits, le premier configurant le module methodOverride(utile dans un contexte RESTful pour le support des verbes PUT et DELETE), le second configurant le répertoire de nos vues.</p>
<p>Notre serveur est ainsi configuré pour servir nos fichiers statiques, gérer les routes que nous allons mettre en place, et est capable de décoder les POST de formulaire et transmettre les paramètres de requêtes à nos callback. Il s'agit d'une configuration lambda, qui répondra à la majeure partie de nos besoins.</p>
<h3>Gestion des erreurs</h3>
<p>Une composante essentielle de toute applications web est la gestion des erreurs, notamment la gestion des erreurs 404 et 500. Node Boilerplate est construit avec une configuration par défaut simple et robuste.</p>
<p><em><strong>Configuration des erreurs 404/500</strong></em></p>
<script src="https://gist.github.com/728506.js"> </script>
<p>Pour de plus amples informations sur la gestion des erreurs dans Express, voici un <a href="http://expressjs.com/guide.html#Error-Handling">lien vers le chapitre correspondant</a> de la documentation Express.</p>
<h3>Routage</h3>
<p>Provenant de la <a href="http://expressjs.com/guide.html#Routing">documentation Express</a>:</p>
<blockquote><p>Express utilizes the HTTP verbs to provide a meaningful, expressive routing API. For example we may want to render a user's account for the path /user/12, this can be done by defining the route below. The values associated to the named placeholders are available as req.params.</p></blockquote>
<p>Autrement dit, Express porte on ne peut mieux son nom! L'api fournie pour configurer nos routes est très expressive, le code se lit avec une facilité déconcertante, même pour quelqu'un n'ayant jamais touché Node ou Express.</p>
<p><em><strong>Exemple de configuration de routes</strong></em></p>
<script src="https://gist.github.com/728569.js"> </script>
<p>Lorsqu'une requête est faîte au serveur, Express confronte l'URL à l'ensemble des routes configurées par nos soins, dans l'ordre de configuration et exécute tout callback défini pour la première route correspondante. Autrement dit, vous devez placer les routes de plus haute priorité en première place et affiner ensuite. Vous pouvez le voir en oeuvre avec la configuration de la route 404 (app.get('/*')).</p>
<p>Vous pouvez passer le contrôle à la prochaine route correspondante en appelant le troisième argument, la fonction next(). Quand plusieurs routes correspondent au même chemin, les contrôleurs seront alors exécutes en ordre jusqu'à ce qu'un callback ne fasse pas d'appel à next(). Cette méthode est aussi utile dans la gestion de nos erreurs où l'on sera amené à utiliser quelque chose comme: next(new Error('an hopefully meaningful error message')).</p>
<h3>Les vues</h3>
<p>Une fois que nous avons correctement mis en place nos routes, il reste à fournir à l'utilisateur une réponse. C'est quelque chose que nous avons déjà fait dans les extraits de code précédents sans toutefois nous y attarder (res.send() et res.render())</p>
<p>Express supporte de nombreux systèmes de templates différents:
<ul>
<li><a href="http://jade-lang.com/">Jade</a></li>
<li><a href="http://github.com/visionmedia/haml.js">Haml</a></li>
<li><a href="http://github.com/visionmedia/ejs">EJS</a></li>
<li><a href="http://github.com/mauricemach/coffeekup">CoffeeKup</a></li>
<li><a href="https://github.com/kof/node-jqtpl">jQuery Templates</a></p></li>
</ul>
<p>Le nom des vues prennent la forme de vue.ENGINE, où ENGINE correspond au nom du module qui sera "required" (fait d'importer la dépendance dans Node). Par exemple, utiliser view.ejs importera le module ejs via require('ejs'). L'utilisation des vues se fait par l'entremise de res.render() (qu'on a pu voir en oeuvre dans le chapitre de gestion des erreurs).</p>
<p><em>Exemple utilisant haml pour retourner index.haml</em></p>
<script src="https://gist.github.com/728600.js"> </script>
<p>Express tentera alors de rendre notre vue index.haml contenue dans le répertoire /views (que l'on a configuré plus tôt via server.set('views', __dirname + '/views');). Par défaut, express passera le contenu d'index.haml en tant que variable locale body à layout.haml. Nous pouvons toujours l'empêcher en utlisant l'option layout: false lors de l'appel à res.render().</p>
<p>Express propose de nombreuses possibilités au niveau des vues et est très flexible. La <a href="http://expressjs.com/guide.html#View-Rendering">documentation correspondante</a> vous en apprendra davantage, notamment sur le support des <a href="http://expressjs.com/guide.html#View-Partials">vues partielles</a> (partial() depuis une vue).</p>
<h2>Github API</h2>
<p>Github fournit une <a href="http://develop.github.com/">API REST</a> complète permettant de récupérer informations et contenus des repository Github. L'API propose également un mécanisme d'authentification et permet d'effectuer des opérations de mise à jour comme suivre ou arrêter le suivi d'un repo/user, d'ouvrir/fermer un bug (Github issue), de mettre à jour nos informations utilisateur(mail, nom, site, ...) ou celle d'un repository nous appartenant, etc. L'API permet également d'utiliser une fonction de callback en ajoutant simplement le paramètre ?callback=js à n'importe quel appel, le résultat JSON sera alors encapsulé dans cette fonction, de manière à pouvoir l'exécuter et permettre la mise en place de requêtes cross-domain (JSONP).</p>
<p>Dans le cadre de cette article et la conception de notre client Github, nous n'utiliserons que l'API <a href="http://develop.github.com/p/repo.html">Repo</a> et <a href="http://develop.github.com/p/object.html">Object</a>.</p>
<h3>node-github</h3>
<p>Différentes librairies sont disponibles pour accéder à l'API Github, et ce dans plusieurs langages (Java, Python, Ruby, ...). Le contexte de notre exercice se trouvant être Node, ce sont les implémentations javascript qui nous intéressent le plus, et notamment le module <a href="http://github.com/ajaxorg/node-github">node-github</a> qui propose une API asyncrhone et orientée objet.</p>
<h3>node-markdown</h3>
<p>Un peu hors du contexte de l'API Github, mais nous en aurons besoin plus tard. Nous utiliserons donc également le module <a href="https://github.com/andris9/node-markdown">node-markdown</a> pour formater nos données depuis le format markdown vers le format HTML. Nous aurions pu également effectuer ce traitement coté client par l'utilisation de <a href="http://attacklab.net/showdown/">showdown</a> sur lequel le module node est basé.</p>
<h3>Prise en main rapide</h3>
<script src="https://gist.github.com/724653.js"> </script>
<p>Ce bout de code permet de récupérer le contenu d'un fichier spécifique sur un repository, et de le retourner au format HTML que nous affichons simplement dans la console node. Ici, nous disposons du nom de l'utilisateur github, du repo concerné, du sha du tree associé (qu'on peut trouver à coté de chaque commit) et le chemin du fichier. Bon nombre de requête requièrent ce paramètre sha, mais il en existe quelques unes permettant de les récupérer via l'API Github (la liste des blobs notamment).</p>
<p>Pour se faire la main, nous pouvons également utiliser node en ligne de commande, importer le module github et commencer à jouer avec son API, voici un exemple d'utilisation de l'API Repo pour récupérer la liste des repositories d'un utilisateur (ici, moi-même).</p>
<img class="mk-blog-img-center" src="{{site.baseurl}}assets/img/express/node-github-cmd-e1291511000234.png" alt="node command line">
<h3>Conception du module githuber</h3>
<p>Dans le contexte de l'exercice décrit ici, nous n'aurons besoin que de deux méthode de l'API du module github: listBlobs et getRawData.</p>
<p>Le premier appel permet de récupérer la liste complète des fichiers du repo avec notamment le sha associé à chacun des fichiers, le deuxième permettant de récupérer le contenu brut du fichier (peu importe le format demandé yaml, json etc.).</p>
<p>Lorsque j'ai commencé à implémenter directement tout ça, je me suis vite rendue compte que le fichier server.js (notre fichier principal décrivant la configuration de notre serveur, route, erreur etc.) allait vite devenir illisible. Il est donc de bon ton d'utiliser le mécanisme de module de Node, reposant sur la convention <a href="http://www.commonjs.org/">commonJS</a>, pour hiérarchiser et structurer un peu notre code, sans parler de découplage des responsabilités.</p>
<p>Voyez ce module comme un service (que j'ai bien failli appeller githubService...), le composant logiciel fournissant l'essentiel du traitement des données reçues par github (filtre, format des données, etc.). Ceci correspondra à notre "logique métier" (bien que la plupart de cette logique se trouve du coté de Github qui fournit le service et dont nous sommes consommateurs).</p>
<p><em><strong>Code du module arbitrairement appelé “githuber”</strong></em></p>
<script src="https://gist.github.com/728677.js"> </script>
<p>On voit bien la nature asynchrone de node qui pourra en rebuter certains au premier abord. Il s'agit effectivement d'un paradigme complètement différent de ce à quoi nous sommes habitués, il est très important de savoir quand nous nous situons dans un contexte asynchrone où l'on doit utiliser le passage de callback (présent dans la signature des deux méthodes publiques fournises) ou l'utlisation des évenements Node (<a href="demystifying-events-in-node">demystifying-events-in-node</a>).</p>
<p>Décrivons maintenant rapidement les méthodes listBlobs et getArticle qui seront utilisées depuis nos contrôleurs (les callbacks configurés pour chaque route de notre application).</p>
<h4>githuber.listBlobs(cb, next)</h4>
<p>Cette méthode permet de récupérer la liste complète des fichiers d'un repository donné (celui décrit dans le module config).</p>
<ul>
<li><p>next {Function}: La fonction next fournie par Express en troisième argument de toute fonction configurée sur une route. Notamment utilisé ici pour gérer les différentes erreurs possibles.</p></li>
<li><p>cb {Function}: Callback invoqué lorsque le service Gihub nous a retourné la liste des blobs avec succès. Le contexte (ou binding, sens du mot clé this dans la fonction invoquée) du callback référence le module githuber. Le seul paramètre accesible depuis cb représente la liste des résultats ([{title: 'title', sha: 'sha'}, ...]). L'appel au service github n'est effectué qu'une fois, au moment du premier appel à listBlobs. Tout appel suivant retournera la valeur du tableau stocké en mémoire.</p></li>
</ul><p>Seuls les fichiers de type markdown nous intéressent. Le service github nous retournant l'ensemble des fichiers du repo, la méthode effectue un petit test sur chacun d'entre eux grâce à l'expression régulière /([\w|-]+).(md|markdown)/ permettant par la même occasion de déterminer le titre du fichier (qui sera affiché à l'utilisateur).</p>
<p><em><strong>Exemple d'utilisation</strong></em></p>
<script src="https://gist.github.com/728690.js"> </script>
<p>Ici encore, nous retrouvons toute l'asynchronicité de Node, la fonction passé à listBlobs sera alors invoqué dès que nous disposerons de résultat à consommer. Nous récupérons également les informations du repo (un simple getter sur la variable contenant ces infos). Nous passons alors à la vue différentes valeurs dont data(disponible en paramètre de ce callback), correspondant à notre liste de blobs.</p>
<p>La vue corresponante list.ejs utilise une vue partielle pour afficher tout ceci à l'utilisateur. Les vues partielles sont une manière simple et efficace de "boucler" dans vos vues. Au lieu d'utiliser une structure itérative, vous pouvez laisser Express gérer l'itération pour vous. Pour chaque élément de la collection, la vue item.ejs est utilisée avec une variable locale (item ici) référençant l'élément en cours d'itération.</p>
<p><em><strong>Utilisation dans les vues</strong></em></p>
<script src="https://gist.github.com/728700.js"> </script>
<h4>githuber.getArticle(sha, next, cb)</h4>
<p>Cette méthode permet de récupérer le contenu d'un article donné. Il s'agit du contenu brut (text/plain) et ce quelque soit le format spécifié au niveau de la requête github (yaml, json, etc.). Ce contenu est alors transmis au callback passé en paramètre aprés avoir été traité par le module markdown, permettant la conversion vers le format HTML.</p>
<ul>
<li><p>sha {String}: Valeur du sha du fichier à récupérer (ex: 365b84e0fd92c47ecdada91da47f2d67500b8e31). Cette valeur est retournée par la méthode listBlobs.</p></li>
<li><p>next {Function}: La fonction next fournie par Express en troisième argument de toute fonction configurée sur une route. Notamment utilisé ici pour gèrer les différentes erreurs possibles.</p></li>
<li><p>cb {Function}: Callback à invoquer dès lors que la donnée est prête à etre consommée. Le contexte de la fonction étant le module githuber, son paramètre unique étant un objet {title: 'title', content: '<p>content...</p>' }</p></li>
</ul>
<p><em><strong>Exemple d'utilisation</strong></em></p>
<script src="https://gist.github.com/728717.js"> </script>
<p><em><strong>Vue associée</strong></em></p>
<script src="https://gist.github.com/728719.js"> </script>
<p>Remarquez l'utilisation de l'opérateur <%- %> au lieu de <%= %> pour empêcher l'échappement de notre string HTML.</p>
<h2>Conclusion, conclusion</h2>
<p>Nous arrivons alors à la fin de cette article. Nous avons présenté et pris en main les principales fonctionnalités d'Express, appréhendé et utilisé l'API Github Object pour finir sur la conception de notre propre module.</p>
<p>Vous pourrez retrouver l'ensemble du code relatif à cette article sur ce repository github: <a href="https://github.com/MkLabs/idonthaveanameyet">github.com/MkLabs/idonthaveanameyet</a></p>
<p>Le nom du projet n'est vraiment pas très originale et j'avoue avoir manquer d'inspiration sur le coup. Je n'avais pas d'idée de nom, le projet s'est alors appelé de lui même idonthaveanameyet...</p>
<p>Dont voici un petit screenshot:
<img class="mk-blog-img-center" src="{{site.baseurl}}assets/img/express/node-md-githubapi-sample.png" alt="Demo"></p>
<p>L'interface très épuré reprends la structure et le style de la nouvelle interface twitter (sans bien sûr aller aussi loin). Une simple liste accessible depuis l'accueil permet de cliquer sur chacun des fichiers markdown du repo afin d'afficher leur contenu. Ici, l'exemple porte sur le repo npm qui dispose de l'ensemble de la documentation sous ce format.</p>
<p>Pour ceux désirant jouer un peu avec cette appli et changer les informations du repository utilisé, il vous suffit de suivre les quelques étapes suivantes:</p>
<script src="https://gist.github.com/729156.js"> </script>
<p>Le fichier config.js vous permet de facilement modifier les informations du repository utilisé (name, repo, branch)</p>
<script src="https://gist.github.com/728736.js"> </script>
<p>Vous pouvez alors lancer votre navigateur favori et tester <a href="http://localhost:15001">http://localhost:15001</a>.</p>
<p>Mais comme je suis un brave gars, je vous ai mis en place une version en ligne disponible via <a href="http://blogit.mklog.fr">http://blogit.mklog.fr</a>, le repository configuré étant Node bien entendu ;).</p>
<p><strong>Ressource pour aller plus loin</strong></p>
<ul>
<li><a href="http://expressjs.com/">http://expressjs.com/</a></li>
<li><a href="http://visionmedia.github.com/masteringnode/">http://visionmedia.github.com/masteringnode/</a></li>
<li><a href="http://howtonode.org/getting-started-with-express">http://howtonode.org/getting-started-with-express</a></li>
</ul>
<p><strong>Connect</strong></p>
<ul>
<li><a href="https://github.com/senchalabs/connect">https://github.com/senchalabs/connect</a></li>
<li><a href="http://senchalabs.github.com/connect/">http://senchalabs.github.com/connect/</a></li>
</ul>