Expressを使用した基本的なNode.JSアプリケーション

みなさんこんにちは。

Expressを使用して基本的なNode.JSアプリケーションを作成する方法に関する記事を探していました。より正確には、プロジェクトに必要な基本構造を探していましたが、似たようなものは見つかりませんでした。

したがって、私はそれを行う方法とそれがどのように見えるべきかと同じことを説明するために、自分で書くことにしました。



カットの下の詳細。 ご注意 たくさんのテキストとコード。



始める前に、これが私の最初の記事であることに注意してください。 おそらく、何かを考慮に入れないか、その逆もあります。何かもっと注意を払うことに集中します。記事の訂正と説明、およびアプローチに感謝します。



タスクは次のとおりです。リクエストを処理し、正しいページまたはリクエストに対する正しい回答を表示できる基本的なアプリケーションを作成します。



だから。 アプリケーション内で使用されるモジュールから始めましょう。



express -  ,   http- mongoose - ,     MongoDB mongodb - native-driver    MongoDB  connect-mongo -    express  session node-uuid -      (   -) async -      ,  Promise ejs-locals -  ,     nconf -       ( config.json) string -      ,      ,  html    validator -   winston -    
      
      







次のコマンドを使用して、各モジュールをインストールできます。

npm install <<モジュール名>> --save



--saveは 、他のマシンにアプリケーションをさらにデプロイするために、モジュールを依存関係(package.json)で保存するために必要です。



アプリケーションの構造は次のとおりです。



  /config config.json index.js /middleware checkAuth.js errorHandler.js index.js /models user.js /public /*JS, CSS, HTML static files*/ /routes authentication.js error.js index.js main.js register.js /utils index.js log.js mongoose.js validate.js /views index.ejs manage.js package.json server.js
      
      







実際、各ディレクトリとそのスクリプトの塩が何であるかを説明します。

アプリケーション全体を開始する最も重要なスクリプトから始めましょう。



server.js



 var express = require('express'), http = require('http'), app = express(), middleware = require('./middleware')(app, express), config = require('./config'), log = require('./utils/log')(app, module); http.createServer(app).listen(config.get('port'), function(){ log.info('Express server listening on port ' + config.get('port')); });
      
      







server.jsでepxress appを作成し、必要なすべてのミドルウェアアプリケーションが接続されているミドルウェアモジュールを接続します。

次に、構成で指定されたポートを介したすべての着信接続を処理するサーバーを作成します。



package.json



 { "name": "test_express_app", "version": "0.0.1", "private": true, "scripts": { "start": "node server.js" }, "dependencies": { "express": "~3.4.6", "mongoose": "~3.8.1", "node-uuid": "~1.4.1", "nconf": "~0.6.9", "winston": "~0.7.2", "async": "~0.2.9", "mongodb": "~1.3.22", "ejs-locals": "~1.0.2", "connect-mongo": "~0.4.0", "validator": "~2.0.0", "string": "~1.7.0" } }
      
      







プロジェクトに必要なすべての情報と、必要なすべてのパッケージが含まれています。



manage.js



 var mongoose = require('./utils/mongoose'), async = require('async'), User = require('./models/user'), log = require('./utils/log')(null, module), config = require('./config'); function openConnection(cb) { mongoose.connection.on('open', function () { log.info('connected to database ' + config.get('db:name')); cb(); }); } function dropDatabase(cb) { var db = mongoose.connection.db; db.dropDatabase(function () { log.info('dropped database ' + config.get('db:name')); cb(); }); } function createBaseUser(cb) { var admin = new User({ username: 'admin', password: config.get('project:admin:password'), email: config.get('project:admin:email'), role: 1 }); admin.save(function () { log.info('created database ' + config.get('db:name')); log.info('created base admin user'); cb(); }); } function ensureIndexes(cb) { async.each(Object.keys(mongoose.models), function (model, callback) { mongoose.models[model].ensureIndexes(callback); }, function () { log.info('indexes ensured completely'); cb(); }); } function closeConnection() { mongoose.disconnect(); log.info('disconnected'); } async.series( [ openConnection, dropDatabase, createBaseUser, ensureIndexes ], closeConnection );
      
      







データベースを初期化して、サーバーが動作するデフォルトの情報を入力する必要があります。



config



config.json



 { "port": 3000, "db": { "connection": "mongodb://localhost", "name": "db_name", "options": { "server": { "socketOptions": { "keepAlive": 1 } } } }, "session": { "secret": "secret_key", "key": "cid", "cookie": { "path": "/", "httpOnly": true, "maxAge": null } } }
      
      







index.js



 var nconf = require('nconf'); var path = require('path'); nconf.argv() .env() .file({file: path.join(__dirname, 'config.json')}); module.exports = nconf;
      
      







config.jsファイルには、データベースに接続するための設定とセッション設定に関する情報が含まれています。

configを操作するには、 nconfパッケージを使用します 。これにより、getterおよびsetterを介して設定オブジェクトを操作できます。 シンボルを使用してネストされたオブジェクトを使用することもできます。



 config.get('session:secret'); config.get('session:cookie:path');
      
      







ミドルウェア



 module.exports = function (app, express) { var ejs = require('ejs-locals'), path = require('path'), config = require('../config'), mongoose = require('../utils/mongoose'), MongoStore = require('connect-mongo')(express), router = require('../routes'), errorHandler = require('./errorHandler')(app, express), checkAuth = require('./checkAuth'); /** * Page Rendering * */ app.engine('html', ejs); app.engine('ejs', ejs); app.set('views', path.join(__dirname, '../views')); app.set('view engine', 'ejs'); /** * Favicon * */ app.use(express.favicon('public/images/favicon.ico')); /** * Logger * */ if (app.get('env') == 'development') { app.use(express.logger('dev')); } /** * Session * */ app.use(express.bodyParser()); app.use(express.cookieParser()); app.use(express.session({ secret: config.get('session:secret'), key: config.get('session:key'), cookie: config.get('session:cookie'), store: new MongoStore({mongoose_connection: mongoose.connection}) })); /** * Authorization Access * */ app.use(checkAuth); /** * Routing * */ app.use(app.router); router(app); /** * Public directory * */ app.use(express.static(path.join(__dirname, '../public'))); app.use("/public", express.static(path.join(__dirname, '../public'))); /** * Error handing * */ app.use(errorHandler); };
      
      







したがって、サーバーコードの主要部分を詰まらせることなく、すべてのミドルウェアを接続します。アプリケーションの作成に合わせて、拡張する必要があるかもしれません。



私も注意したい-errorHandlerミドルウェアは、サーバーエラーを独自に処理し、エラーページを表示するように設計されています



errorHandler



 var config = require('../config'); var sendHttpError = function (error, res) { res.status(error.status); if (res.req.xhr) { res.json(error); } else { res.render('error', { error: { status: error.status, message: error.message, stack: config.get('debug') ? error.stack : '' }, project: config.get('project') }); } }; module.exports = function (app, express) { var log = require('../utils/log')(app, module), HttpError = require('../error').HttpError; return function(err, req, res, next) { if (typeof err === 'number') { err = new HttpError(err); } if (err instanceof HttpError) { sendHttpError(err, res); } else { if (app.get('env') === 'development') { express.errorHandler()(err, req, res, next); } else { log.error(err); err = new HttpError(500); sendHttpError(err, res); } } }; };
      
      







ミドルウェアcheckAuthにも注意したい

 var HttpError = require('../error').HttpError; module.exports = function (req, res, next) { if (!req.session.user) { return next(new HttpError(401, "You are not authorized!")); } next(); };
      
      





これは、セッションの存在の要求をチェックし、セッションがない場合はエラーをスローします。 グローバルミドルウェアとして使用するか、使用する特定の方法を指定できます。



 app.get('/user-info', checkAuth, function (req, res, next) { //do your staff });
      
      







モデル



Mongooseの助けを借りて、データを操作するための独自のモデルを作成します。 モデルの例は次のようになります。



 var crypto = require('crypto'), mongoose = require('../utils/mongoose'), Schema = mongoose.Schema, async = require('async'); var User = new Schema({ username: { type: String, unique: true, required: true }, hashedPassword: { type: String, required: true }, salt: { type: String, required: true } }); User.methods.encryptPassword = function (password) { return crypto.createHmac('sha1', this.salt).update(password).digest('hex'); }; User.virtual('password') .set(function (password) { this._plainPassword = password; this.salt = Math.random() + ''; this.hashedPassword = this.encryptPassword(password); }) .get(function () { return this._plainPassword; }); User.methods.checkPassword = function (password) { return this.encryptPassword(password) === this.hashedPassword; }; module.exports = mongoose.model('User', User);
      
      







公開



このディレクトリには、外部からアクセス可能なすべてのスクリプトとcssファイルが含まれます。 このオプションは、次の設定を使用して実装されます。



 /** * Public directory * */ app.use(express.static(path.join(__dirname, '../public'))); app.use("/public", express.static(path.join(__dirname, '../public')));
      
      







ルート



おそらく最も興味深い。 このディレクトリで、ルーティングを担当するモジュールを宣言します。 index.jsファイル



 var main = require('./main'), register = require('./register'), authentication = require('./authentication'), error = require('./error'); module.exports = function (app) { app.get('/', main.home); app.post('/register', register.requestRegistration); app.get('/users', authentication.users); app.get('/users/:id', authentication.user); app.get('*', error['404']); };
      
      







ここでは、単にルートを宣言し、実行を他のモジュールに委任するだけです。 たとえば、 ルート「/」

 /** * Method: GET * URI: / * */ exports.home = function(req, res, next) { res.render('index'); };
      
      







実際にはそれだけです。 この場合、ベースアプリケーションの動作方法。 セッションをサポートするために、対応するミドルウェアを含めます。 たとえば 、特定の検証と登録など、ユーザーに関連付けられているすべてのビジネスロジックをmodels / user.jsに転送します。



PS:

この記事の執筆では、情報がI. Kantorのスクリーンキャストから使用されました。 スクリーンキャストへのリンク。

MongoDBのコースの情報も使用しました



All Articles