![](https://habrastorage.org/storage3/4cf/018/d13/4cf018d13e00510b24cd7e9a31f607b8.jpg)
翻蚳è ããïŒç§èªèº«ãããæè¿node.jsãåŠã³å§ããŸããã ééããªããã€ã³ã¿ãŒãããäžã«ã¯ãåå¿è åãã®å€ãã®åªããïŒïŒïŒããã¥ã¢ã«ããããŸãïŒç¹ã«ããããããªã©ïŒã ããããèè Krasimir Tsonevã®ãã®ããã¥ã¢ã« ïŒåœŒã®ãã«ããããã¯ããã°ãåç §ããããšããå§ãããŸãïŒã¯ãMVCãã¿ãŒã³ãšããŒã¹ã䜿çšããŠExpressã¢ãžã¥ãŒã«ã«åºã¥ããæ¬æ Œçãªnode.jsã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã»ã¹ã«ã€ããŠèª¬æããŠãããããç¹ã«æ³šç®ã«å€ããããã«æããŸããã MongoDBããŒã¿ã èè ã¯ãŸãããã¹ããªã©ã®éèŠãªããšã«æ³šæãæã£ãŠããŸãã
翻蚳
ãã®èšäºã§ã¯ãã¯ã©ã€ã¢ã³ãéšåãåããæ¬æ ŒçãªWebãµã€ããšããµã€ãã®ã³ã³ãã³ãçšã®ã³ã³ãããŒã«ããã«ãæ§ç¯ããŸãã ãæ³åã®ãšãããããã°ã©ã ã®æçµããŒãžã§ã³ã«ã¯å€æ°ã®ç°ãªããã¡ã€ã«ãå«ãŸããŠããŸãã ãã®ã¬ã€ãã段éçã«äœæããããã»ã¹ã®éçºãå®å šã«ç£èŠããŸãããããã¹ãŠã®ãã¡ã€ã«ããã®äžã«å«ããããšã¯å§ããŸããã§ããã ãã ãããœãŒã¹ã³ãŒãã¯GitHubã§å ¥æã§ããŸãããã§ãã¯ã¢ãŠãããããšã匷ããå§ãããŸãã
ãšã³ããªãŒ
Expressã¯ãæé«ã®Nodeãã¬ãŒã ã¯ãŒã¯ã®1ã€ã§ãã åªããéçºè ãµããŒããšå€æ°ã®äŸ¿å©ãªæ©èœãåããŠããŸãã Expressã«ã¯ããããæ±ãããã®ãã¹ãŠã®åºæ¬äºé ãç¶²çŸ ããçŽ æŽãããèšäºããããããããŸãã ããããä»ã¯ããå°ãæãäžããŠãæ¬æ ŒçãªWebãµã€ããäœæããçµéšãå ±æããããšæããŸãã äžè¬ã«ããã®èšäºã¯Expressèªäœã«é¢ããã ãã§ãªããéçºè ãå©çšã§ããä»ã®å£ããªãçŽ æŽãããããŒã«ãšã®çµã¿åããã«ã€ããŠã説æããŠããŸãã
Node.jsã«ç²Ÿéããã·ã¹ãã ã«ã€ã³ã¹ããŒã«ããããšãããã³ãã®äžã«ããã€ãã®ã¢ããªã±ãŒã·ã§ã³ãæ¢ã«äœæããŠããããšãä¿¡ããŠããŸãã
Expressãã¬ãŒã ã¯ãŒã¯ã¯Connectã«åºã¥ããŠããŸã ã ããã¯ãå€ãã®äŸ¿å©ãªæ©èœãåããããã«ãŠã§ã¢æ©èœã®ã»ããã§ãã ããã«ãŠã§ã¢é¢æ°ãšã¯äœãã«èå³ããããªããããã«å°ããªäŸããããŸãïŒ
var connect = require('connect'), http = require('http'); var app = connect() .use(function(req, res, next) { console.log("That's my first middleware"); next(); }) .use(function(req, res, next) { console.log("That's my second middleware"); next(); }) .use(function(req, res, next) { console.log("end"); res.end("hello world"); }); http.createServer(app).listen(3000);
ããã«ãŠã§ã¢é¢æ°ã¯ãåºæ¬çã«ããªã¯ãšã¹ããªããžã§ã¯ããšå¿çãªããžã§ã¯ãããã©ã¡ãŒã¿ãŒãšããŠåãå ¥ããé¢æ°ã§ããã次ã«åŒã³åºãããã³ãŒã«ããã¯é¢æ°ã§ããããŸãã åããã«ãŠã§ã¢é¢æ°ã¯ãå¿çãªããžã§ã¯ãã䜿çšããŠå¿çããããã¹ããªãŒã ã次ã®ã³ãŒã«ããã¯é¢æ°ã«æž¡ããã決å®ããŸãã äžèšã®äŸã§ã¯ã2çªç®ã®é¢æ°ã§nextïŒïŒã¡ãœããåŒã³åºããåé€ãããšãæååãhello worldãã¯ã¯ã©ã€ã¢ã³ãã«éä¿¡ãããŸããã äžè¬çã«ããããExpressã®ä»çµã¿ã§ãã ããã¯ééããªãããªãã®æéãç¯çŽããããã€ãã®å®çŸ©æžã¿ã®ããã«ãŠã§ã¢æ©èœãåããŠããŸãã ããšãã°ããªã¯ãšã¹ãããã£ã解æããã³ã³ãã³ãã¿ã€ãapplication / json ã application / x-www-form-urlencodedããã³multipart / form-dataããµããŒãããããã£ããŒãµãŒã§ãã ãŸãã¯ã CookieããããŒã解æããããŒãCookieã®ååã§ãããªããžã§ã¯ããreq.cookiesãã£ãŒã«ãã«å ¥åããCookieããŒãµãŒã
å®éãExpressã¯ããèªäœãConnectãã¬ãŒã ã¯ãŒã¯ã§ã©ããããã«ãŒãã£ã³ã°ããžãã¯ãªã©ã®ããã€ãã®æ©èœã§è£å®ããŠãã«ãŒãã£ã³ã°ããã»ã¹ãã¹ã ãŒãºã«é²ããŸãã 以äžã¯ãGETèŠæ±ãåŠçããäŸã§ãã
app.get('/hello.txt', function(req, res){ var body = 'Hello World'; res.setHeader('Content-Type', 'text/plain'); res.setHeader('Content-Length', body.length); res.end(body); });
èšçœ®
Expressã®ã€ã³ã¹ããŒã«ã«ã¯2ã€ã®ãªãã·ã§ã³ããããŸãã 1ã€ç®ã¯ããã®èª¬æãpackage.jsonãã¡ã€ã«ã«é 眮ããŠnpm installã³ãã³ããå®è¡ããããšã§ãïŒãã®ããã±ãŒãžãããŒãžã£ãŒã®ååã¯ãno problem manããè¡šããŠãããããªãžã§ãŒã¯ããããŸã:)ïŒã
{ "name": "MyWebSite", "description": "My website", "version": "0.0.1", "dependencies": { "express": "3.x" } }
ãã¬ãŒã ã¯ãŒã¯ã³ãŒãã¯node_modulesãã£ã¬ã¯ããªã«é 眮ãããã€ã³ã¹ã¿ã³ã¹ãäœæã§ããŸãã ç§ã¯ä»£æ¿æ段ã奜ã¿ãŸãïŒã³ãã³ãã©ã€ã³ã npm install -g expressãå®è¡ããŠExpressãã€ã³ã¹ããŒã«ããã ãã§ãã ããã«ãããæ°ããCLIããŒã«ãäœæãããŸãã ããšãã°ã次ã®å ŽåïŒ
express --sessions --css less --hogan app
Expressã¯ãæ§ææžã¿ã®ã¢ããªã±ãŒã·ã§ã³ãã¬ãŒã ã¯ãŒã¯ãçæããŸãã 以äžã¯ã ãšã¯ã¹ãã¬ã¹ïŒ1ïŒã³ãã³ããªãã·ã§ã³ã®ãªã¹ãã§ãã
Usage: express [options] Options: -h, --help output usage information -V, --version output the version number -s, --sessions add session support -e, --ejs add ejs engine support (defaults to jade) -J, --jshtml add jshtml engine support (defaults to jade) -H, --hogan add hogan.js engine support -c, --css add stylesheet support (less|stylus) (defaults to plain css) -f, --force force on non-empty directory
ã芧ã®ãšããã䜿çšå¯èœãªãªãã·ã§ã³ã®ãªã¹ãã¯å°ããã§ãããããã§ååã§ãã éåžžã lessã©ã€ãã©ãªãCSSããªããã»ããµãšããŠäœ¿çšãã hoganãã³ãã¬ãŒããšã³ãžã³ã䜿çšããŸãã ãã®äŸã§ã¯ãã»ãã·ã§ã³ã®ãµããŒããå¿ èŠã§ãã--sessionsãªãã·ã§ã³ã¯ãã®åé¡ã解決ããŸãã ããŒã ãå®äºãããšããããžã§ã¯ãã®æ§é ã¯æ¬¡ã®ããã«ãªããŸãã
/public /images /javascripts /stylesheets /routes /index.js /user.js /views /index.hjs /app.js /package.json
package.jsonãã¡ã€ã«ãèŠããšãå¿ èŠãªãã¹ãŠã®äŸåé¢ä¿ãããã«è¿œå ãããŠããããšãããããŸãã ãããããŸã ã€ã³ã¹ããŒã«ãããŠããŸããã ãããè¡ãã«ã¯ãnpm installã³ãã³ããå®è¡ããŸã ããã®åŸã node_modulesãã£ã¬ã¯ããªã衚瀺ãããŸã ã
äžèšã®ã¢ãããŒãã¯ããŠãããŒãµã«ãšåŒã¶ã«å€ããªãããšãç解ããŠããŸãã ããšãã°ãã«ãŒããã³ãã©ãå¥ã®ãã£ã¬ã¯ããªãªã©ã«é 眮ããå¿ èŠãããå ŽåããããŸãã ãããã次ã®ããã€ãã®ç« ã§ç€ºãããããã«ãçæãããæ§é ã«å€æŽãå ããŸããããã¯éåžžã«ç°¡åã§ãã ããã«åºã¥ããŠã expressïŒ1ïŒã³ãã³ããåã«ãã³ãã¬ãŒããžã§ãã¬ãŒã¿ãšããŠäœ¿çšããããšããå§ãããŸãã
é«éé ä¿¡
ãã®ãã¥ãŒããªã¢ã«ã§ã¯ãFastDeliveryãšããæ¶ç©ºã®äŒç€Ÿã®ç°¡åãªWebãµã€ããäœæããŸããã å®æãããã¶ã€ã³ã®ã¹ã¯ãªãŒã³ã·ã§ããã次ã«ç€ºããŸãã
![](https://habrastorage.org/storage3/297/10a/078/29710a07849d9ad20abc3f4543c11a4b.jpg)
ãã®ã¬ã€ãã®æåŸã«ãæ©èœããã³ã³ãããŒã«ããã«ãåããæ¢è£œã®Webã¢ããªã±ãŒã·ã§ã³ããããŸãã ã¢ã€ãã¢ã¯ããµã€ãã®åéšåãåéšåã®å¥ã ã®é åã§ç®¡çããæ©èœãäœæããããšã§ãã ã¬ã€ã¢ãŠãã¯Photoshopã§äœæãããCSSïŒlessïŒããã³HTMLïŒhoganïŒãã¡ã€ã«ã«ã«ãããããŸããã ããã§ã¯ã¹ã©ã€ã¹ããã»ã¹ã«ã€ããŠã¯èª¬æããŸãããããã¯ããã®èšäºã§ã®è°è«ã®äž»é¡ã§ã¯ãªãããã§ããããã®éšåã«é¢ããŠè³ªåãããå Žåã¯ããæ°è»œã«è³ªåããŠãã ããã ã¹ã©ã€ã¹ãçµäºãããšãã¢ããªã±ãŒã·ã§ã³ãã¡ã€ã«ã®æ¬¡ã®æ§é ãåŸãããŸãã
/public /images (there are several images exported from Photoshop) /javascripts /stylesheets /home.less /inner.less /style.css /style.less (imports home.less and inner.less) /routes /index.js /views /index.hjs (home page) /inner.hjs (template for every other page of the site) /app.js /package.json
以äžã«ã管çã§ãããµã€ãèŠçŽ ã®ãªã¹ãã瀺ããŸãã
- ããŒã ããŒãžïŒäžå€®ã®ãããŒ-ã¿ã€ãã«ãšããã¹ãïŒ
- ããã°ïŒèšäºã®è¿œå ãåé€ãç·šéïŒ
- ãµãŒãã¹ããŒãž
- æ¡ç³å ŽããŒãžïŒç å Žã§ã¯ãªãå°éçãªæé·:)ïŒ
- ãåãåããããŒãž
æ§æ
å§ããåã«ãããªããã°ãªããªãããšãããã€ããããŸãã æ§æã®ã»ããã¢ããã¯ãã®ãããªãã®ã®1ã€ã§ãã å°èŠæš¡ãªãµãŒããŒããããŒã«ã«ãäžéãæŠéã®3ã€ã®ç°ãªããµãŒããŒã«å±éãããããšãæ³åããŠã¿ãŸãããã åœç¶ã3ã€ã®ç°å¢ãã¹ãŠã®èšå®ã¯ç°ãªãããããã®ãããªç¶æ³ã«ååã«æè»ãªã¡ã«ããºã ãå®è£ ããå¿ èŠããããŸãã ãåç¥ã®ããã«ãånodejsã¹ã¯ãªããã¯ã³ã³ãœãŒã«ã¢ããªã±ãŒã·ã§ã³ãšããŠå®è¡ãããŸãã ã€ãŸããçŸåšã®ç°å¢ã決å®ããã³ãã³ãã«ãã©ã¡ãŒã¿ãŒãç°¡åã«å²ãåœãŠãããšãã§ããŸãã åŸã§ãã¹ããæžãã®ã䟿å©ã«ãªãããã«ããã®éšåãå¥ã®ã¢ãžã¥ãŒã«ã«ã©ããããŸããã /config/index.jsãã¡ã€ã«ïŒ
var config = { local: { mode: 'local', port: 3000 }, staging: { mode: 'staging', port: 4000 }, production: { mode: 'production', port: 5000 } } module.exports = function(mode) { return config[mode || process.argv[2] || 'local'] || config.local; }
çŸæç¹ã§ã¯ãã¢ãŒãïŒã¢ãŒãïŒãšããŒãïŒããŒãïŒã®2ã€ã®ãã©ã¡ãŒã¿ãŒãããããŸããã ãæ³åã®ãšãããã¢ããªã±ãŒã·ã§ã³ã¯ç°ãªããµãŒããŒäžã®ç°ãªãããŒãã䜿çšããŸãã ãã®ããã app.jsãã¡ã€ã«ã§ãµã€ãã®ãšã³ããªãã€ã³ããæŽæ°ããå¿ èŠããããŸãã
... var config = require('./config')(); ... http.createServer(app).listen(config.port, function(){ console.log('Express server listening on port ' + config.port); });
æ§æãåãæ¿ããã«ã¯ãç°å¢ã®ååãã³ãã³ãã®æåã®ãã©ã¡ãŒã¿ãŒã«è¿œå ããã ãã§ãã äŸïŒ
node app.js staging
åºåãããŸãïŒ
Express server listening on port 4000
çŸåšããã¹ãŠã®èšå®ã¯1ãæã«ä¿åãããŠããã管çã容æã§ãã
ãã¹ã
ç§ã¯TDDã®å€§ãã¡ã³ã§ãã ãã®èšäºã§åãäžãããã¹ãŠã®åºæ¬ã¯ã©ã¹ããã¹ãã§ã«ããŒããããã«ããŸãã 絶察ã«ãã¹ãŠã®ãã¹ããäœæããã®ã«ã¯å€ãã®æéããããããšã«åæããŸãããäžè¬ã«ããããã¢ããªã±ãŒã·ã§ã³ã®äœææ¹æ³ã§ãã ç§ã®ãæ°ã«å ¥ãã®ãã¹ããã¬ãŒã ã¯ãŒã¯ã®1ã€ã¯ãžã£ã¹ãã³ã§ãã ãã¡ããã npmããã±ãŒãžãããŒãžã£ãŒã§å©çšã§ããŸãã
npm install -g jasmine-node
ãã¹ããä¿åãããã£ã¬ã¯ããªãäœæããŸãããã æåã«ãã¹ãããã®ã¯ãæ§æãã¡ã€ã«ã§ãã ãã¹ããã¡ã€ã«ã®ååã¯.spec.jsã§çµããå¿ èŠãããããããã¡ã€ã«config.spec.jsãåŒã³åºããŸãã
describe("Configuration setup", function() { it("should load local configurations", function(next) { var config = require('../config')(); expect(config.mode).toBe('local'); next(); }); it("should load staging configurations", function(next) { var config = require('../config')('staging'); expect(config.mode).toBe('staging'); next(); }); it("should load production configurations", function(next) { var config = require('../config')('production'); expect(config.mode).toBe('production'); next(); }); });
jasmine-node ./testsã³ãã³ããå®è¡ãããšã次ã®ããã«è¡šç€ºãããŸãã
Finished in 0.008 seconds 3 tests, 6 assertions, 0 failures, 0 skipped
ä»ãç§ã¯æåã«å®è£ ãæžãã次ã«ãã¹ããæžããŸããã ããã¯TDDã¢ãããŒãã§ã¯ãããŸãããã次ã®ç« ã§ã¯å察ã®ããšãè¡ããŸãã
ãã¹ããæžãã®ã«ååãªæéããããããšã匷ããå§ãããŸãã å®å šã«ãã¹ããããã¢ããªã±ãŒã·ã§ã³ã«åããã®ã¯ãããŸããã
æ°å¹Žåãç§ã¯éåžžã«éèŠãªäœããããè¯ãã¢ããªã±ãŒã·ã§ã³ãäœæããã®ã«åœ¹ç«ã€äœãã«æ°ä»ããŸããã æ°ããã¯ã©ã¹ãæ°ããã¢ãžã¥ãŒã«ããŸãã¯åãªãããžãã¯ã®äœæãéå§ãããã³ã«ã次ã®ããšãèªåããŠãã ããã
ãããã©ã®ããã«ãã¹ãã§ããŸããïŒ
ãã®è³ªåã«å¯Ÿããçãã¯ãã³ãŒããããå¹ççã«èšè¿°ããåªããAPIãäœæãããã¹ãŠãé©åã«åé¢ããããããã¯ã«åå²ããã®ã«åœ¹ç«ã¡ãŸãã ã¹ãã²ããã£ã³ãŒãã®ãã¹ãã¯äœæã§ããŸããã ããšãã°ãäžèšã®æ§æãã¡ã€ã«ïŒ /config/index.js ïŒã§ãã¢ãžã¥ãŒã«ã³ã³ã¹ãã©ã¯ã¿ãŒã«ã¢ãŒããéä¿¡ããæ©èœãè¿œå ããŸããã ããªãã¯é©ããããããŸããïŒäž»ãªã¢ã€ãã¢ã¯ã³ãã³ãã©ã€ã³åŒæ°ããã¢ãŒãã®å€ãååŸããããšãªã®ã§ããªãç§ã¯ãããããã®ã§ããïŒ ç°¡åã§ãããã¹ãããå¿ èŠãããããã§ãã 1ãæåŸã«æŠéãµãŒããŒã®æ§æã䜿çšããŠäœãããã¹ãããå¿ èŠããããããŒãã¹ã¯ãªããã代æ¿ãã©ã¡ãŒã¿ãŒã§å®è¡ãããããšãæ³åããŠã¿ãŸãããã ãããŠããã®å°ããªæ¹åããªããã°å€æŽãå ããããšã¯ã§ããŸããã ãã®åã®å°ããªã¹ãããã¯ãå°æ¥ã®ã¢ããªã±ãŒã·ã§ã³ã®å±éã§èµ·ããããåé¡ãé²ããŸãã
ããŒã¿ããŒã¹
åçãªWebãµã€ããæ§ç¯ããå Žåãæ å ±ãä¿åããããŒã¿ããŒã¹ãå¿ èŠã§ãã ãã®ãããç§ã¯ãã®æ瀺ã®ããã«mongodbãéžæããŸãã ã Mongoã¯NoSQLããŒã¿ããŒã¹ã§ãã ããã«ã€ã³ã¹ããŒã«æé ããããŸã ãç§ã¯WindowsãŠãŒã¶ãŒãªã®ã§ãWindows ã®ã€ã³ã¹ããŒã«æé ã«åŸããŸãã ã ã€ã³ã¹ããŒã«ãå®äºããããããã©ã«ãã§ããŒã27017ããªãã¹ã³ããMongoDBããŒã¢ã³ãèµ·åããŸãããããã£ãŠãçè«çã«ã¯ããã®ããŒãã«æ¥ç¶ããŠmongodbãµãŒããŒãšã¡ãã»ãŒãžã亀æããæ©äŒããããŸãã ããŒãã¹ã¯ãªãããä»ããŠãããè¡ãã«ã¯ã mongodb module / driverãå¿ èŠã§ã ã ãã®æé ã®ãœãŒã¹ãã¡ã€ã«ãããŠã³ããŒãããå Žåãã¢ãžã¥ãŒã«ã¯æ¢ã«package.jsonãã¡ã€ã«ã«è¿œå ãããŠããŸãã ããã§ãªãå Žåã¯ã äŸåé¢ä¿ããããã£ã«ãmongodbãïŒã1.3.10ããè¿œå ãã npm installã³ãã³ããå®è¡ããŸãã 次ã«ãmongodbãµãŒããŒãå®è¡ãããŠãããã©ããã確èªãããã¹ããäœæããŸãã
/tests/mongodb.spec.jsãã¡ã€ã«ïŒ
describe("MongoDB", function() { it("is there a server running", function(next) { var MongoClient = require('mongodb').MongoClient; MongoClient.connect('mongodb://127.0.0.1:27017/fastdelivery', function(err, db) { expect(err).toBe(null); next(); }); }); });
mongodbã¯ã©ã€ã¢ã³ãã¡ãœãã.connectã®ã³ãŒã«ããã¯é¢æ°ã¯ã dbãªããžã§ã¯ããåãåããŸãã åŸã§ããŒã¿ã®ç®¡çã«äœ¿çšããŸãã ããã¯ãã¢ãã«å ã§ã¢ã¯ã»ã¹ããå¿ èŠãããããšãæå³ããŸãã ããŒã¿ããŒã¹ãç §äŒãããã³ã«æ°ããMongoClientãªããžã§ã¯ããäœæããããšã¯ãå§ãã§ããŸããã ãã®ãããExpressãµãŒããŒã®èµ·åãããŒã¿ããŒã¹ã«æ¥ç¶ããã³ãŒã«ããã¯é¢æ°ã«è»¢éããŸããã
MongoClient.connect('mongodb://127.0.0.1:27017/fastdelivery', function(err, db) { if(err) { console.log('Sorry, there is no mongo db server running.'); } else { var attachDB = function(req, res, next) { req.db = db; next(); }; http.createServer(app).listen(config.port, function(){ console.log('Express server listening on port ' + config.port); }); } });
ç°å¢æ§æèšå®ãã¡ã€ã«ããããããmongodbãµãŒããŒã®ãã¹ãåãšããŒããããã«é 眮ããæ¥ç¶URLã次ã®ããã«å€æŽããããšããå§ãããŸãã
'mongodbïŒ//' + config.mongo.host + 'ïŒ' + config.mongo.port + '/ fastdelivery'
http.createServeré¢æ°ã®åŒã³åºãã®çŽåã«è¿œå ããããã«ãŠã§ã¢é¢æ°attachDBã«ç¹ã«æ³šæããŠãã ãã ã ãã®å°ããªè¿œå ã®ãããã§ããªã¯ãšã¹ããªããžã§ã¯ãã®.dbããããã£ãå ¥åããŸãã è¯ããã¥ãŒã¹ã¯ãã«ãŒã決å®äžã«ããã€ãã®æ©èœãèšå®ã§ããããšã§ãã äŸïŒ
app.get('/', attachDB, function(req, res, next) { ... })
ãããã£ãŠãExpressã¯ãããããattachDBé¢æ°ãåŒã³åºããŠãã«ãŒããã³ãã©ãŒã«å ¥ãããã«ããŸãã ãããçºçãããšããªã¯ãšã¹ããªããžã§ã¯ãã«.dbããããã£ãèšå®ãããããã䜿çšããŠããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ã§ããŸãã
MVC
ç§ãã¡ã¯ãã¹ãŠMVCãã¿ãŒã³ã«ç²ŸéããŠããŸã ã åé¡ã¯ãExpressã§ãããé©çšããæ¹æ³ã§ãã ãããã«ãããããã¯è§£éã®åé¡ã§ãã 次ã®ããã€ãã®ç« ã§ã¯ãã¢ãã«ããã¥ãŒãã³ã³ãããŒã©ãŒãšããŠæ©èœããã¢ãžã¥ãŒã«ãäœæããŸãã
ã¢ãã«
ã¢ãã«ã¯ãã¢ããªã±ãŒã·ã§ã³ã®ããŒã¿ãåŠçãããã®ã§ãã MongoClientãªããžã§ã¯ãã«ãã£ãŠè¿ãããdbãªããžã§ã¯ããžã®ã¢ã¯ã»ã¹æš©ãå¿ èŠã§ãã ããŸããŸãªã¿ã€ãã®ã¢ãã«ãå¿ èŠã«ãªãå¯èœæ§ããããããã¢ãã«ã«ã¯ãããæ¡åŒµããæ¹æ³ãå¿ èŠã§ãã ããšãã°ã BlogModelãŸãã¯ContactsModelã¢ãã«ãäœæããå ŽåããããŸãã ãããè¡ãã«ã¯ãæåã«ãã¹ã/tests/base.model.spec.jsãäœæããå¿ èŠããããŸãã ãããŠããããã®ãã¹ããäœæããããšã«ãããã¢ãã«ãå¿ èŠãªããšã ããè¡ãããã以å€ã¯äœãããªãããšãä¿èšŒã§ããŸãã
var Model = require("../models/Base"), dbMockup = {}; describe("Models", function() { it("should create a new model", function(next) { var model = new Model(dbMockup); expect(model.db).toBeDefined(); expect(model.extend).toBeDefined(); next(); }); it("should be extendable", function(next) { var model = new Model(dbMockup); var OtherTypeOfModel = model.extend({ myCustomModelMethod: function() { } }); var model2 = new OtherTypeOfModel(dbMockup); expect(model2.db).toBeDefined(); expect(model2.myCustomModelMethod).toBeDefined(); next(); }) });
å®éã®dbãªããžã§ã¯ãã®ä»£ããã«ãã¢ãã¯ãªããžã§ã¯ããæž¡ãããšã«ããŸããã ããã¯ãåŸã§ç¹å®ã®äœãããã¹ããããå Žåã«è¡ãããŸããããã¯ãããŒã¿ããŒã¹ããã®ããŒã¿ã«äŸåããŸãã ãã®ããŒã¿ãæåã§å®çŸ©ããæ¹ãã¯ããã«ç°¡åã§ãã
ãããã¿ã€ãmodule.exportsãå€æŽããå¿ èŠããããŸãããå ã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãã®ãŸãŸã«ããŠããå¿ èŠããããããã¡ãœããæ¡åŒµã®å®è£ ã¯å°ãé£ããã§ãã 幞ããªããšã«ãã³ãŒãã®ããã©ãŒãã³ã¹ããã§ãã¯ãããã¹ãããã§ã«äœæããŠããŸãã äžèšã®ã³ãŒãã¹ããããã®ããŒãžã§ã³ã¯æ¬¡ã®ããã«ãªããŸãã
module.exports = function(db) { this.db = db; }; module.exports.prototype = { extend: function(properties) { var Child = module.exports; Child.prototype = module.exports.prototype; for(var key in properties) { Child.prototype[key] = properties[key]; } return Child; }, setDB: function(db) { this.db = db; }, collection: function() { if(this._collection) return this._collection; return this._collection = this.db.collection('fastdelivery-content'); } }
ããã§ã¯ã2ã€ã®ãã«ããŒã¡ãœãããå®çŸ©ãããŠããŸãã ããŒã¿ããŒã¹ããã®ã³ã¬ã¯ã·ã§ã³ã®dbãªããžã§ã¯ããšã²ãã¿ãŒã®ã»ãã¿ãŒã
æåº
ãã¥ãŒã¯ç»é¢ã«æ å ±ã衚瀺ããŸãã ç°¡åã«èšãã°ããã¥ãŒã¯ãã©ãŠã¶ãŒã«å¿çãéä¿¡ããã¯ã©ã¹ã§ãã Expressã¯ããããè¡ãç°¡åãªæ¹æ³ãæäŸããŸãã
res.render('index', { title: 'Express' });
å¿çãªããžã§ã¯ãã¯ãç掻ã楜ã«ããåªããAPIãåããã©ãããŒã§ãã ãã ããç¬èªã®ã¢ãžã¥ãŒã«ãäœæããŠããã®æ©èœã«çµã¿èŸŒãããšã奜ã¿ãŸãã ãã¥ãŒã®æšæºãã£ã¬ã¯ããªã¯ãã³ãã¬ãŒãã«çœ®ãæãããããã¥ãŒã®å€ããã£ã¬ã¯ããªã¯ããŒã¹ãã¥ãŒã¯ã©ã¹ãæäŸããŸãã
ãã®å°ããªå€æŽã«ã¯ãå¥ã®å€æŽãå¿ èŠã§ãã ãã³ãã¬ãŒããã¡ã€ã«ãå¥ã®ãã£ã¬ã¯ããªã«ããããšãExpressã«éç¥ããå¿ èŠããããŸãã
app.set('views', __dirname + '/templates');
ãŸããå¿ èŠãªãã®ããã¹ãŠæ±ºå®ãããã¹ããäœæããŸãããã®åŸãå®è£ ãéå§ããŸãã 次ã®èŠä»¶ãæºããã¢ãžã¥ãŒã«ãå¿ èŠã§ãã
- ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã¯ãå¿çãªããžã§ã¯ããšãã³ãã¬ãŒãåãåãåãå¿ èŠããããŸã
- ããŒã¿ãªããžã§ã¯ããåãå ¥ãããã³ãã¬ãŒãåºåã¡ãœãããå¿ èŠã§ãã
- æ¡åŒµå¯èœã§ãªããã°ãªããŸããã
é©ããããããŸããïŒãªããã¬ãŒã³ããŒã·ã§ã³ã¯ã©ã¹ãæ¡åŒµããå¿ èŠããã£ãã®ã§ããïŒ åœŒã¯response.renderã¡ãœãããåŒã³åºãã ãã§ã¯ãããŸãããïŒ å®éãå®éã«ã¯ãå¥ã®ããããŒãéä¿¡ããããå¿çãªããžã§ã¯ããæäœãããããå¿ èŠãããå ŽåããããŸãã ããšãã°ãJSONã§éä¿¡ãããããŒã¿ãåŠçããŸãã
var data = {"developer": "Krasimir Tsonev"}; response.contentType('application/json'); response.send(JSON.stringify(data));
ãããæ¯åè¡ã代ããã«ã HTMLView ã¯ã©ã¹ãšJSONViewã¯ã©ã¹ãçšæããããšã¯çŽ æŽãããããšã§ãã ãŸãã¯ãXMLããŒã¿ããã©ãŠã¶ã«éä¿¡ããXMLViewã¯ã©ã¹ã åãã³ãŒããç¹°ãè¿ãã³ããŒããŠè²Œãä»ãããããããã®ãããªæ©èœãæ¢ã«å®è£ ãããŠãã倧ããªWebã¢ããªã±ãŒã·ã§ã³ãäœæããæ¹ãç°¡åã§ãã
以äžã¯ã / views / Base.jsã¯ã©ã¹ã®ãã¹ãã§ãã
var View = require("../views/Base"); describe("Base view", function() { it("create and render new view", function(next) { var responseMockup = { render: function(template, data) { expect(data.myProperty).toBe('value'); expect(template).toBe('template-file'); next(); } } var v = new View(responseMockup, 'template-file'); v.render({myProperty: 'value'}); }); it("should be extendable", function(next) { var v = new View(); var OtherView = v.extend({ render: function(data) { expect(data.prop).toBe('yes'); next(); } }); var otherViewInstance = new OtherView(); expect(otherViewInstance.render).toBeDefined(); otherViewInstance.render({prop: 'yes'}); }); });
ã¬ã³ããªã³ã°ïŒèŠèŠåïŒããã¹ãããã«ã¯ãã¬ã€ã¢ãŠããäœæããå¿ èŠããããŸããã ãã®å Žåããã¹ãã®æåã®éšåã§ãExpressãã¬ãŒã ã¯ãŒã¯ã®å¿çãªããžã§ã¯ããã·ãã¥ã¬ãŒããããªããžã§ã¯ããäœæããŸããã ãã¹ãã®2çªç®ã®éšåã§ã¯ãåºæ¬ã¯ã©ã¹ãç¶æ¿ããç¬èªã®ã¬ã³ããªã³ã°ã¡ãœããã䜿çšããå¥ã®Viewã¯ã©ã¹ãäœæããŸããã
ã¯ã©ã¹ã³ãŒã/views/Base.js ïŒ
module.exports = function(response, template) { this.response = response; this.template = template; }; module.exports.prototype = { extend: function(properties) { var Child = module.exports; Child.prototype = module.exports.prototype; for(var key in properties) { Child.prototype[key] = properties[key]; } return Child; }, render: function(data) { if(this.response && this.template) { this.response.render(this.template, data); } } }
ããã§ããã¹ãçšã®ãã£ã¬ã¯ããªã«3ã€ã®ãã¹ããããã jasmine-node ./testsã³ãã³ããå®è¡ãããšãçµæã¯æ¬¡ã®ããã«ãªããŸãã
Finished in 0.009 seconds 7 tests, 18 assertions, 0 failures, 0 skipped
ã³ã³ãããŒã©ãŒ
ã«ãŒãã«ã€ããŠè©±ããã©ã®ããã«æ±ºå®ããã®ãèŠããŠããŸããïŒ
app.get('/', routes.index);
äžèšã®äŸã®ã«ãŒãã®åŸã«ããèšå·ã/ãã¯ã³ã³ãããŒã©ãŒã§ãã ããã¯ã ãªã¯ãšã¹ã ã ã¬ã¹ãã³ã¹ ãã³ãŒã«ããã¯é¢æ°nextïŒïŒãåãåãããã«ãŠã§ã¢é¢æ°ã§ãã
exports.index = function(req, res, next) { res.render('index', { title: 'Express' }); };
äžèšã¯ãExpressã䜿çšããå Žåã®ã³ã³ãããŒã©ãŒã®å€èŠ³ã説æããŠããŸãã expressïŒ1ïŒã³ãã³ãã¯ã routesãšããååã§ãã£ã¬ã¯ããªãäœæããŸãããç§ãã¡ã®å Žåã¯ã controllersãšåŒã°ããæ¹ãè¯ãã§ãããã ãã¡ã€ã«æ§é ããã®ãã¿ãŒã³ã«äžèŽããããã«ååãå€æŽããŸããã
åãªãå°ããªã¢ããªã±ãŒã·ã§ã³ä»¥äžã®ãã®ãæ§ç¯ããŠãããããæ¡åŒµå¯èœãªåºæ¬ã¯ã©ã¹ãäœæããããšããå§ãããŸãã ãã¹ãŠã®ã³ã³ãããŒã©ãŒã«æ©èœãè¿œå ããå¿ èŠãããå Žåããã®åºæ¬ã¯ã©ã¹ã¯ã¢ããªã³ãå®è£ ããã®ã«æé©ãªå Žæã§ãã ç¹°ãè¿ããŸãããç§ã¯æåã«ãã¹ããæžããŠããã®ã§ãåºæ¬ã¯ã©ã¹ã«å¿ èŠãªãã®ãå®çŸ©ããŸãããïŒ
- ãªããžã§ã¯ããååŸããŠæ°ããåã€ã³ã¹ã¿ã³ã¹ãè¿ãæ¡åŒµå¯èœãªã¡ãœãããå¿ èŠã§ã
- åã€ã³ã¹ã¿ã³ã¹ã«ã¯runã¡ãœãããå¿ èŠã§ããããã¯å€ãè¯ãããã«ãŠã§ã¢é¢æ°ã§ã
- ã³ã³ãããŒã©ãèå¥ããååããããã£ãå¿ èŠã§ã
- åºæ¬ã¯ã©ã¹ããç¶æ¿ãããç¬ç«ãããªããžã§ã¯ããäœæã§ããã¯ãã§ãã
ã»ãã®æ°ç¹ã§ãããåŸã§æ©èœãè¿œå ããããšãã§ããŸãã
ãã¹ãã¯æ¬¡ã®ããã«ãªããŸãã
var BaseController = require("../controllers/Base"); describe("Base controller", function() { it("should have a method extend which returns a child instance", function(next) { expect(BaseController.extend).toBeDefined(); var child = BaseController.extend({ name: "my child controller" }); expect(child.run).toBeDefined(); expect(child.name).toBe("my child controller"); next(); }); it("should be able to create different childs", function(next) { var childA = BaseController.extend({ name: "child A", customProperty: 'value' }); var childB = BaseController.extend({ name: "child B" }); expect(childA.name).not.toBe(childB.name); expect(childB.customProperty).not.toBeDefined(); next(); }); });
以äžã¯/controllers/Base.jsã®å®è£ ã§ãïŒ
var _ = require("underscore"); module.exports = { name: "base", extend: function(child) { return _.extend({}, this, child); }, run: function(req, res, next) { } }
ãã¡ãããååå«ã¯ã©ã¹ã«ã¯ãç¬èªã®ããžãã¯ãå®è£ ããç¬èªã®runã¡ãœãããå¿ èŠã§ãã
FastDelivery Webãµã€ã
ãŸããMVCã¢ãŒããã¯ãã£ã«é©ããã¯ã©ã¹ã®ã»ãããããããã¹ãŠã®ã¢ãžã¥ãŒã«ããã¹ãã§ã«ããŒããŸããã ããã§ãæ¶ç©ºã®äŒç€ŸFastDeliveryã®ãµã€ããåŒãç¶ãæ±ãæºåãã§ããŸããã ãµã€ãã2ã€ã®éšåïŒãŠãŒã¶ãŒéšåãšç®¡çããã«ïŒã§æ§æãããããšãæ³åããŠã¿ãŸãããã ãŠãŒã¶ãŒéšåã¯ãããŒã¿ããŒã¹ã«ä¿åãããŠããæ å ±ããšã³ããŠãŒã¶ãŒã«æ瀺ããããã®ãã®ã§ãã管çããã«ã¯ããã®æ å ±ã管çããããã®ãã®ã§ããæåŸããå§ããŸãããã
å¶åŸ¡ç€
æåã«ã管çããã«ããŒãžãæäŸããã·ã³ãã«ãªã³ã³ãããŒã©ãŒãäœæããŸãããã
ãã¡ã€ã«/controllers/Admin.jsïŒ
var BaseController = require("./Base"), View = require("../views/Base"); module.exports = BaseController.extend({ name: "Admin", run: function(req, res, next) { var v = new View(res, 'admin'); v.render({ title: 'Administration', content: 'Welcome to the control panel' }); } });
ã³ã³ãããŒã©ãŒãšãã¥ãŒã®äºåã«äœæãããåºæ¬ã¯ã©ã¹ã䜿çšããŠã管çããã«ã®ãšã³ããªãã€ã³ããç°¡åã«äœæã§ããŸããViewã¯ã©ã¹ã¯ããã³ãã¬ãŒããã¡ã€ã«ã®ååãåãå ¥ããŸããäžèšã®ã³ãŒãã«ãããšããã¡ã€ã«ã¯admin.hjsãšããååã§ã/ templatesãã£ã¬ã¯ããªã«é 眮ããå¿ èŠããããŸãããã®å 容ã¯æ¬¡ã®ããã«ãªããŸãã
<!DOCTYPE html> <html> <head> <title>{{ title }}</title> <link rel='stylesheet' href='/stylesheets/style.css' /> </head> <body> <div class="container"> <h1>{{ content }}</h1> </div> </body> </html>
ïŒãã®æ瀺ãçãèªã¿ãããããããã«ãããã§ã¯åãã³ãã¬ãŒãã®ã³ãŒããæäŸããŸãããGitHubãããœãŒã¹ã³ãŒããããŠã³ããŒãããããšã匷ããå§ãããŸããïŒ
次ã«ãã³ã³ãããŒã©ãŒã衚瀺ããããã«ãã¢ããªã«ã«ãŒããè¿œå ããå¿ èŠããããŸãã.jsïŒ
var Admin = require('./controllers/Admin'); ... var attachDB = function(req, res, next) { req.db = db; next(); }; ... app.all('/admin*', attachDB, function(req, res, next) { Admin.run(req, res, next); });
Admin.runã¡ãœãããããã«ãŠã§ã¢é¢æ°ãšããŠçŽæ¥éä¿¡ããªãããšã«æ³šæããŠãã ãããããã¯ãã³ã³ããã¹ããä¿æããããã§ãããããè¡ãå ŽåïŒ
app.all('/admin*', Admin.run);
Adminãªããžã§ã¯ãã®thisãšããåèªã¯ããŸã£ããå¥ã®å ŽæãæããŸãã
管çããã«ã®ä¿è·
/ adminã§å§ãŸãåããŒãžã¯ä¿è·ããå¿ èŠããããŸãããããå®çŸããããã«ãçµã¿èŸŒã¿ã®Expressããã«ãŠã§ã¢æ©èœã§ããSessionsã䜿çšããŸããã»ãã·ã§ã³ãšåŒã°ãããªã¯ãšã¹ãã«ãªããžã§ã¯ããè¿œå ããã ãã§ãã次ã®2ã€ã®ããšãè¡ãããã«ã管çã³ã³ãããŒã©ãŒãå€æŽããå¿ èŠããããŸãã
- ã»ãã·ã§ã³ãå©çšå¯èœãã©ããã確èªããå¿ èŠããããŸããããã§ãªãå Žåã¯ãèªèšŒãã©ãŒã ã衚瀺ããŸã
- ãŠãŒã¶ãŒåãšãã¹ã¯ãŒããããŒã¿ããŒã¹ã®ãŠãŒã¶ãŒåãšãã¹ã¯ãŒããšäžèŽããå Žåãæ¿èªãã©ãŒã ããéä¿¡ãããããŒã¿ãåãå ¥ãããŠãŒã¶ãŒãæ¿èªããå¿ èŠããããŸã
以äžã¯ãäžèšã®èŠä»¶ãæºããå°ããªãã«ããŒé¢æ°ã§ãã
authorize: function(req) { return ( req.session && req.session.fastdelivery && req.session.fastdelivery === true ) || ( req.body && req.body.username === this.username && req.body.password === this.password ); }
æåã«ãã»ãã·ã§ã³ãªããžã§ã¯ããä»ããŠãŠãŒã¶ãŒãèªèããããšããã¹ã¯ãªãããå®è¡ãããŸãã次ã«ããã©ãŒã ããã®ããŒã¿ãéä¿¡ããããã©ããã確èªããŸãããã®å Žåãããã«ãŠã§ã¢é¢æ°bodyParserãçšæããrequest.bodyãªããžã§ã¯ããããã©ãŒã ã®ããŒã¿ãå©çšã§ããŸãã次ã«ããŠãŒã¶ãŒåãšãã¹ã¯ãŒããäžèŽãããã©ããã確èªããŸãããããŠãã³ã³ãããŒã©ãŒããrunã¡ãœãããå®è¡ãããšããæ¥ãŸããããã®ã¡ãœããã¯ãæ°ããäœæããããã«ããŒïŒãã¹ãŠã®ã³ã³ãããŒã©ãŒã®åºæ¬ã©ãããŒïŒã䜿çšããŸãããã§ãã¯ïŒãŠãŒã¶ãŒãæ¿èªãããŠããå Žåãã³ã³ãããŒã«ããã«ã衚瀺ããããã§ãªãå Žåã¯æ¿èªããŒãžã衚瀺ããŸãã
run: function(req, res, next) { if(this.authorize(req)) { req.session.fastdelivery = true; req.session.save(function(err) { var v = new View(res, 'admin'); v.render({ title: 'Administration', content: 'Welcome to the control panel' }); }); } else { var v = new View(res, 'admin-login'); v.render({ title: 'Please login' }); } }
ã³ã³ãã³ã管ç
ãã®èšäºã®åé ã§è¿°ã¹ãããã«ã管çãããã®ããããããããŸããããã»ã¹ãç°¡çŽ åããããã«ã1ã€ã®ã³ã¬ã¯ã·ã§ã³ã«ãã¹ãŠã®ããŒã¿ãä¿æããŸããããåãšã³ããªã«ã¯ãã¿ã€ãã«ãããã¹ããç»åãããã³ã¿ã€ãã®ããããã£ããããŸããåŸè ãã¬ã³ãŒãã®ææè ã決å®ããŸããããšãã°ãé£çµ¡å ããŒãžã«ã¯ãé£çµ¡å ãã¿ã€ãã®ãšã³ããªã1ã€ã ãå¿ èŠã§ãããããã°ããŒãžã«ã¯ããã«å€ãã®ãšã³ããªãå¿ èŠã§ãããã®ããããšã³ããªãè¿œå ãåé€ãç·šéããã«ã¯ã3ã€ã®æ°ããããŒãžãè¿œå ããå¿ èŠããããŸããæ°ãããã³ãã¬ãŒãã®äœæãã¹ã¿ã€ãªã³ã°ãããã³ã³ã³ãããŒã©ãŒãžã®æ°ãããã®ã®è¿œå ãéå§ããåã«ãMongoDBãµãŒããŒãšã¢ããªã±ãŒã·ã§ã³ã®éã«ããã¢ãã«ã®ã¯ã©ã¹ãäœæããå¿ èŠããããŸãããã¡ããã䟿å©ãªAPIãæäŸããŸãã
// /models/ContentModel.js var Model = require("./Base"), crypto = require("crypto"), model = new Model(); var ContentModel = model.extend({ insert: function(data, callback) { data.ID = crypto.randomBytes(20).toString('hex'); this.collection().insert(data, {}, callback || function(){ }); }, update: function(data, callback) { this.collection().update({ID: data.ID}, data, {}, callback || function(){ }); }, getlist: function(callback, query) { this.collection().find(query || {}).toArray(callback); }, remove: function(ID, callback) { this.collection().findAndModify({ID: ID}, [], {}, {remove: true}, callback); } }); module.exports = ContentModel;
ã¢ãã«ã¯ãåã¬ã³ãŒãã«äžæã®IDãçæããŸããåŸã§æ å ±ãæŽæ°ããããã«å¿ èŠã«ãªããŸãã
é£çµ¡å ããŒãžã«æ°ãããšã³ããªãè¿œå ããå¿ èŠãããå Žåã次ã®ããã«èšè¿°ã§ããŸãã
var model = new (require("../models/ContentModel")); model.insert({ title: "Contacts", text: "...", type: "contacts" });
ãã®ãããmongodbã³ã¬ã¯ã·ã§ã³ã«ã¯éåžžã«åªããããŒã¿ç®¡çAPIããããŸããããã§ããã®ãã¹ãŠã®æ©èœã䜿çšããUIãäœæããæºåãã§ããŸãããä»åã¯ã管çã³ã³ãããŒã©ãŒãããªãå€æŽãããŸããã¿ã¹ã¯ãç°¡çŽ åããããã«ãè¿œå ããã¬ã³ãŒãã®ãªã¹ããšãã¬ã³ãŒããè¿œå /ç·šéããããã®ãã©ãŒã ãçµã¿åãããããšã«ããŸãããäžã®ã¹ã¯ãªãŒã³ã·ã§ããã§ãããããã«ãããŒãžã®å·ŠåŽã¯ãªã¹ãçšã«ãå³åŽã¯ãã©ãŒã çšã«äºçŽãããŠããŸãã
![](https://habrastorage.org/storage3/85a/a4e/96c/85aa4e96c85cf660c6ec30fc6b1c1eab.jpg)
ãã¹ãŠã®ã³ã³ãããŒã«ã1ããŒãžã«è¡šç€ºãããšããããšã¯ããã®ããŒãžãã¬ã³ããªã³ã°ããéšåã«çŠç¹ãåãããå¿ èŠãããããšãæå³ããŸããå ·äœçã«ã¯ããã³ãã¬ãŒãã«éä¿¡ããããŒã¿ã«çŠç¹ãåãããå¿ èŠããããŸãããããã£ãŠã次ã®ãããªããã€ãã®çµ±åããããã«ããŒé¢æ°ãäœæããŸããã
var self = this; ... var v = new View(res, 'admin'); self.del(req, function() { self.form(req, res, function(formMarkup) { self.list(function(listMarkup) { v.render({ title: 'Administration', content: 'Welcome to the control panel', list: listMarkup, form: formMarkup }); }); }); });
ã¯ããããã¯å°ãlooksãã§ãããããã¯ç§ãæãããã«æ£ç¢ºã«åäœããŸããæåã®ãã«ããŒã¯delã¡ãœããã§ãçŸåšã®GETãã©ã¡ãŒã¿ãŒããã§ãã¯ããaction = deleteïŒid = [ã¬ã³ãŒãã®ID]ã®çµã¿åãããèŠã€ããå Žåã察å¿ããããŒã¿ãã³ã¬ã¯ã·ã§ã³ããåé€ããŸãã2çªç®ã®é¢æ°ã¯formãšåŒã°ããäž»ã«ããŒãžã®å³åŽã«ãã©ãŒã ã衚瀺ããŸãããã®é¢æ°ã¯ããã©ãŒã ããµãŒããŒã«å°çãããã©ããã確èªããããŒã¿ããŒã¹å ã®ã¬ã³ãŒããé©åã«æŽæ°ãŸãã¯äœæããŸããæåŸã«ãlistã¡ãœããã¯æ å ±ãååŸããåŸã§ãã³ãã¬ãŒãã«éä¿¡ãããHTMLããŒãã«ãæºåããŸããããã3ã€ã®ãã«ããŒã®å®è£ ã¯ããã®åœä»€ã®ãœãŒã¹ã³ãŒãã«ãããŸãã
以äžã¯ããã¡ã€ã«ã®ã¢ããããŒããåŠçããé¢æ°ã§ãã
handleFileUpload: function(req) { if(!req.files || !req.files.picture || !req.files.picture.name) { return req.body.currentPicture || ''; } var data = fs.readFileSync(req.files.picture.path); var fileName = req.files.picture.name; var uid = crypto.randomBytes(10).toString('hex'); var dir = __dirname + "/../public/uploads/" + uid; fs.mkdirSync(dir, '0777'); fs.writeFileSync(dir + "/" + fileName, data); return '/uploads/' + uid + "/" + fileName; }
ãã¡ã€ã«ããµãŒããŒã«éä¿¡ããããšãèŠæ±ãªããžã§ã¯ãã®.filesããããã£ã«å¯Ÿå¿ããããŒã¿ãå ¥åãããŸãããã®å Žåã次ã®HTMLèŠçŽ ããããŸãã
<input type="file" name="picture" />
ããã¯ãreq.files.pictureãä»ããŠéä¿¡ãããããŒã¿ã«ã¢ã¯ã»ã¹ã§ããããšãæå³ããŸããäžèšã®äŸã«ç€ºãããã«ãreq.files.picture.pathã䜿çšããŠããã¡ã€ã«ã®æªå å·¥ïŒæªå å·¥ïŒã³ã³ãã³ããååŸããŸããããã«ãéä¿¡ããããã¡ã€ã«ã¯ããŠã³ããŒãçšã«äœæããããã£ã¬ã¯ããªã«ä¿åãããæåŸã«ããã®ãã¡ã€ã«ã«å¯Ÿå¿ããURLãè¿ãããŸãããããã®æäœã¯ãã¹ãŠåæã§ãããéåæããŒãžã§ã³ã®readFileSyncãmkdirSyncãããã³writeFileSyncã¡ãœããã䜿çšããããšããå§ãããŸãã
ãŠãŒã¶ãŒéš
æãé£ããéšåã®æºåãã§ããŸããã管çããã«ãåäœããããŒã¿ããŒã¹ã«ä¿åãããŠããæ å ±ã«ã¢ã¯ã»ã¹ã§ããContentModelã¯ã©ã¹ããããŸããããã§å¿ èŠãªã®ã¯ããŠãŒã¶ãŒéšåã®ã³ã³ãããŒã©ãŒãäœæããä¿åãããã³ã³ãã³ãã«ãã€ã³ãããããšã§ãããããããŒã ããŒãžã®ã³ã³ãããŒã©ãŒã§ã- /controllers/Home.js
module.exports = BaseController.extend({ name: "Home", content: null, run: function(req, res, next) { model.setDB(req.db); var self = this; this.getContent(function() { var v = new View(res, 'home'); v.render(self.content); }) }, getContent: function(callback) { var self = this; this.content = {}; model.getlist(function(err, records) { ... storing data to content object model.getlist(function(err, records) { ... storing data to content object callback(); }, { type: 'blog' }); }, { type: 'home' }); } });
ããŒã ããŒãžã«ã¯ãã¿ã€ãããhomeãã®1ã€ã®ãšã³ããªãšãã¿ã€ãããblogãã®4ã€ã®ãšã³ããªãå¿ èŠã§ãã
ã³ã³ãããŒã©ãŒã®æºåãã§ããããapp.jsã§ã³ã³ãããŒã©ãŒãžã®ã«ãŒããè¿œå ããå¿ èŠããããŸãã
app.all('/', attachDB, function(req, res, next) { Home.run(req, res, next); });
å床dbãªããžã§ã¯ãããªã¯ãšã¹ããªããžã§ã¯ãã«ã¢ã¿ããããŸããã»ãšãã©ã®å Žåã管çããã«ã®äœææã«å®è¡ããããã»ã¹ãšåãã§ãã
ãŠãŒã¶ãŒããŒãã®ä»ã®ããŒãžã¯ãã¢ãã«ã¯ã©ã¹ã䜿çšããŠããŒã¿ãåä¿¡ããã³ã³ãããŒã©ãŒãããããã¡ããã«ãŒãããããšããç¹ã§ãã»ãšãã©åãã§ããããã«è©³ãã説æããã2ã€ã®èå³æ·±ãåŽé¢ããããŸããæåã¯ããã°ããŒãžã«ãªã³ã¯ãããŠããŸãããã®ããŒãžã«ã¯ããã¹ãŠã®èšäºãš1ã€ã®èšäºã衚瀺ãããŸããã«ãŒãã®ãã¢ãå®çŸ©ããŸãã
app.all('/blog/:id', attachDB, function(req, res, next) { Blog.runArticle(req, res, next); }); app.all('/blog', attachDB, function(req, res, next) { Blog.run(req, res, next); });
äž¡æ¹ãšãåãã³ã³ãããŒã©ãŒïŒBlogã䜿çšããŸããã2ã€ã®ç°ãªãrunã¡ãœãããåŒã³åºããŸããè¡/ blog /ïŒidã«æ³šæããŠãã ããããã®ã«ãŒãã¯ã/ blog / 4e3455635b4a6f6dccfaa1e50ee71f1cde75222bãªã©ã®URLã«äžèŽããŸãããã®é·ãããã·ã¥ã«ã¯ãreq.params.idããããã£ããã¢ã¯ã»ã¹ã§ããŸããã€ãŸããåçãã©ã¡ãŒã¿ãŒãå®çŸ©ã§ããŸããç§ãã¡ã®å Žåãããã¯ãšã³ããªïŒèšäºïŒã®IDã«ãªããŸããããã«ã€ããŠåŠç¿ããã®ã§ãèšäºããšã«äžæã®ããŒãžãçæã§ããŸãã
2çªç®ã®èå³æ·±ãåŽé¢ã¯ããµãŒãã¹ããã£ãªã¢ãé£çµ¡å ã®ããŒãžãã©ã®ããã«äœæãããã§ãããããã®ãã¹ãŠãããŒã¿ããŒã¹ã®1ã€ã®ã¬ã³ãŒãã®ã¿ã䜿çšããããšã¯æããã§ããåããŒãžã«ã³ã³ãããŒã©ãŒãäœæããå¿ èŠãããå Žåã¯ãåãã³ãŒããã³ããŒããŠè²Œãä»ãããã®äžã®typeãã£ãŒã«ããå€æŽããã ãã§ããrunã¡ãœããã§ã¬ã³ãŒãã¿ã€ããåãå ¥ããåäžã®ã³ã³ãããŒã©ãŒã䜿çšããŠããããè¡ãããè¯ãæ¹æ³ããããŸããã«ãŒãã¯æ¬¡ã®ãšããã§ãã
app.all('/services', attachDB, function(req, res, next) { Page.run('services', req, res, next); }); app.all('/careers', attachDB, function(req, res, next) { Page.run('careers', req, res, next); }); app.all('/contacts', attachDB, function(req, res, next) { Page.run('contacts', req, res, next); });
ãããŠãã³ã³ãããŒã©ãŒã¯æ¬¡ã®ããã«ãªããŸãã
module.exports = BaseController.extend({ name: "Page", content: null, run: function(type, req, res, next) { model.setDB(req.db); var self = this; this.getContent(type, function() { var v = new View(res, 'inner'); v.render(self.content); }); }, getContent: function(type, callback) { var self = this; this.content = {} model.getlist(function(err, records) { if(records.length > 0) { self.content = records[0]; } callback(); }, { type: type }); } });
å±é
Express Webãµã€ãããããã€ããããšã¯ãNode.jsã«ä»ã®ã¢ããªã±ãŒã·ã§ã³ããããã€ããããšãšæ¬è³ªçã«éãã¯ãããŸããã
- ãã¡ã€ã«ã¯ãµãŒããŒã«ã¢ããããŒããããŸã
- ããŒãããã»ã¹ãåæ¢ããå¿ èŠããããŸãïŒå®è¡äžã®å ŽåïŒ
- å¿ èŠãªäŸåé¢ä¿ããã¹ãŠã€ã³ã¹ããŒã«ããã«ã¯ãnpm installã³ãã³ããå®è¡ããŸã
- ã¡ã€ã³ããŒãã¹ã¯ãªãããå床å®è¡ãããŸã
Nodeã¯éåžžã«æ°ãã補åã§ããããã¹ãŠãæåŸ ã©ããã«æ©èœããããã§ã¯ãããŸããããåžžã«æ¹åãè¡ãããŠããããšã«æ³šæããŠãã ãããããšãã°ãforeverã¢ãžã¥ãŒã«ã¯Node.jsã®ç¶ç¶çãªåäœãä¿èšŒããŸãã次ã®ã³ãã³ããå®è¡ããŠå®è¡ã§ããŸãã
forever start yourapp.js
ããã¯ãµãŒããŒã§äœ¿çšãããã®ã§ãããã®å°ããªããŒã«ã¯ã1ã€ã®å€§ããªåé¡ã解決ããŸããnode yourapp.jsã³ãã³ãã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšãã¹ã¯ãªããã倱æãããšããã«ãµãŒããŒãã¯ã©ãã·ã¥ããŸãããæ°žä¹ ã«ã¢ããªã±ãŒã·ã§ã³ãåèµ·åããã ãã§ãã
ç§ã¯ã·ã¹ãã 管çè ã§ã¯ãããŸããããApacheãšNginxã§ããŒãã¢ããªã±ãŒã·ã§ã³ãçµ±åããçµéšãå ±æããããšæããŸããçµ±åã¯éçºããã»ã¹ã®äžéšã ãšèããŠããããã§ãããåãã®ããã«ãApacheã¯éåžžããŒã80ã§å®è¡ãããŸããã€ãŸããlocalhostãŸãã¯localhostã®ãã©ãŠã¶ãŒã«ã¢ã¯ã»ã¹ãããšïŒ80ãApacheãµãŒããŒãæäŸããããŒãžã衚瀺ãããŸãããããããããŒãã¹ã¯ãªããã¯å¥ã®ããŒãã§ãªãã¹ã³ããŠããŸãããããã£ãŠãèŠæ±ãåä¿¡ããŠââç®çã®ããŒãã«éä¿¡ããä»®æ³ãã¹ããè¿œå ããå¿ èŠããããŸããããšãã°ãã¢ãã¬ã¹expresscompletewebsite.devã®äžã§ãããŒã«ã«ã®ApacheãµãŒããŒã§äœæããã°ããã®ãµã€ãããã¹ãããå¿ èŠããããŸããæåã«è¡ãå¿ èŠãããã®ã¯ããã¹ããã¡ã€ã«ã«ãã¡ã€ã³ãè¿œå ããããšã§ãã
127.0.0.1 expresscompletewebsite.dev
ãã®åŸãApacheãµãŒããŒã®æ§æãã£ã¬ã¯ããªã«ããhttpd-vhosts.confãã¡ã€ã«ãå€æŽããå¿ èŠããããŸãã
# expresscompletewebsite.dev <VirtualHost *:80> ServerName expresscompletewebsite.dev ServerAlias www.expresscompletewebsite.dev ProxyRequests off <Proxy *> Order deny,allow Allow from all </Proxy> <Location /> ProxyPass http://localhost:3000/ ProxyPassReverse http://localhost:3000/ </Location> </VirtualHost>
ãµãŒããŒã¯ããŒã80ããã®èŠæ±ãåãå ¥ããŸãããããŒãã¹ã¯ãªããããªãã¹ã³ããããŒã3000ã«èŠæ±ã転éããŸãã
Nginxã®æ§æã¯ã¯ããã«ç°¡åã§ãççŽã«èšã£ãŠãNode.jsããŒã¹ã®ã¢ããªã±ãŒã·ã§ã³ããã¹ãããããã®æè¯ã®éžæã§ãã Apacheæ§æãšåæ§ã«ãhostsãã¡ã€ã«ã«ãã¡ã€ã³ãè¿œå ããå¿ èŠããããŸãããã®åŸãNginxãã€ã³ã¹ããŒã«ãããŠããå Žæã«ãã/ sites-enabledãã£ã¬ã¯ããªã«æ°ãããã¡ã€ã«ãäœæããŸãããã¡ã€ã«ã®å 容ã¯æ¬¡ã®ããã«ãªããŸãã
server { listen 80; server_name expresscompletewebsite.dev location / { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $http_host; } }
åããã¹ãæ§æã§ApacheãšNginxãåæã«èµ·åããããšã¯ã§ããªãããšã«æ³šæããŠãã ãããããã¯ãã©ã¡ããããŒã80ã§ãªãã¹ã³ããããã§ããããã«ãæŠéãµãŒããŒã§äžèšã®ã³ãŒãã¹ããããã䜿çšããå Žåã¯ãã€ã³ã¿ãŒãããã§ãã詳现ãªãµãŒããŒæ§ææ å ±ãæ€çŽ¢ã§ããŸããç§ãèšã£ãããã«ãç§ã¯ãã®åéã®å°é家ã§ã¯ãããŸããã
ãããã«
Expressã¯ãWebã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããããã®åªããåºç€ãæäŸããåªãããã¬ãŒã ã¯ãŒã¯ã§ããããªãèªèº«ãèŠãããšãã§ããããã«ãããã¯éžæã®åé¡ããããã©ã®ããã«æ¡åŒµãããããããŠããã§äœã䜿ããã ãã§ããããã€ãã®çŽ æŽãããããã«ãŠã§ã¢ã䜿çšããŠã«ãŒãã³ã¿ã¹ã¯ãç°¡çŽ åããéçºè ã«ãšã£ãŠæããããããã®ãå®è£ ããããã»ã¹ãæ®ããŸãã
ãœãŒã¹ã³ãŒã
GitHubã®ãã®èšäºã§äœæããWebãµã€ãã®ãœãŒã¹ã³ãŒãã¯https://github.com/tutsplus/build-complete-website-expressjsã§ããåå²ããŠã¢ããã°ã¬ãŒãããŠãã ããããŠã§ããµã€ããç«ã¡äžããããã®æ®µéçãªã¬ã€ãã¯æ¬¡ã®ãšããã§ãã
- ãœãŒã¹ã³ãŒããããŠã³ããŒããã
- ããŠã³ããŒãããã¢ããªã±ãŒã·ã§ã³ã®ãã£ã¬ã¯ããªã«ç§»åããŸã
- npm installãå®è¡ãã
- mongodbããŒã¢ã³ãå®è¡ãã
- ããŒãapp.jsãå®è¡ããŸã