تطبيق BoilerPlate لبناء تطبيقات الويب باستخدام Express و Mongoose.
$ git clone https://github.com/wikiyodo/expressjs-boilerplate.git
$ cd expressjs-boilerplate
$ npm install
$ cp .env.example .env
$ npm run start:staging
├── /.data/
├── /app/
│ ├── Http
│ │ ├── Controllers
│ │ ├── Middleware
│ ├── Model
├── /bootstrap/
│ │ ├── boot-configuration.js
│ │ ├── boot-environment.js
│ │ ├── boot-helper-path.js
│ │ ├── boot-router.js
│ │ ├── index.js
│ │ ├── post-index.js
├── /commands/
│ ├── index.js
│ ├── seed.js
├── /database/
│ ├── /schema/
│ │ ├── bank.js
│ │ ├── users.js
│ ├── /seeds/
│ │ ├── bank.js
│ ├── /connection.js
│ └── /all-seeds.js
├── /global/
│ ├── constants.js
│ ├── user-roles.js
├── /helpers/ *
├── /resources/
│ ├── /lang/
│ ├── /view/
├── /routes/
│ ├── /api/
│ │ ├── index.js
│ │ ├── user.js
│ │ ├── guest.js
│ ├── index.js
│ ├── routes-string.js
├── /tests/
├── .env
├── .env.example
├── .gitignore
├── app.js
├── cmd.js
├── package.json
├── package-lock.json
└── Readme.md
يحتوي Resolver على قائمة بالوحدات النمطية التي يمكن أن تساعد في جوانب مختلفة.
// how to access the resolver
var resolver = require(process.env.resolver);
تستخدم لحلية سلاسل الطريق والكائن
resolver.parser(urlSelector, urlParameters, skipBackSlash);
إرجاع سلسلة من المسار بالنسبة إلى دليل الجذر.
resolver.router('database/all-seeds'); // returns __ROOT_DIRECTORY__/database/all-seeds
إرجاع المسار إلى وحدة اتصال DB.
const resolver = require(process.env.resolver);
var mongoose = require(resolver.connection());
mongoose.model('User', UserSchema);
إرجاع المسار إلى ملف النموذج الذي تم تمريره كمعلمة
const resolver = require(process.env.resolver);
var bankModelPath = pathResolver.model('bank');
const Bank = require(bankModelPath);
إرجاع المسار إلى ملف مخطط قاعدة البيانات تم تمريره كمعلمة
const resolver = require(process.env.resolver);
var bankSchemaPath = resolver.dbSchema('bank');
const BankSchema = require(bankSchemaPath);
var Bank = mongoose.model('Bank', BankSchema);
إرجاع المسار إلى ملف وحدة التحكم التي تم تمريرها كمعلمة
const resolver = require(process.env.resolver);
var userControllerPath = resolver.controllers('user-controller');
const UserController= require(userControllerPath);
UserController.deleteUser(user_id, (err, response)=>{ });
إرجاع المسار إلى ملف الوسيطة التي تم تمريرها كمعلمة
const resolver = require(process.env.resolver);
var authMiddlewarePath= resolver.middleware('auth');
const AuthMiddleware= require(authMiddlewarePath);
app.use('/user', AuthMiddleware);
يتم تضمين جميع الطرق في Project_directory /ROUTES ويتم إرفاقها /تعيينها إلى جهاز التوجيه الأساسي الموجود في /routes/index.js
var express = require('express');
var router = express.Router();
// this contains all API routes.
var apiRouter = require('./api/index');
// this contains all routes that can be accessed via the web browsers
var webRouter = require('./web/index');
var routeString = require('./routes-string');
module.exports = (app) => {
app.use('/api', apiRouter);
app.use('/', apiRouter);
};
على سبيل المثال ، تريد إنشاء نقطة نهاية API للأشخاص للحصول على وقت الخادم الحالي في ملف منفصل (time.js الذي سيحتوي على جميع نقاط النهاية المتعلقة بالوقت).
إنشاء وفتح/routes/API/TIME.JS. ثم يجب أن يبدو المحتوى مثل:
var express = require('express');
var router = express.Router();
// endpoint = /api/time/current
router.get('/current'), (req, res)=>{
res.status = 200;
res.send({time:Date.now});
res.end();
});
module.exports = router;
...
const TimeRouter = require('./time'); // this loads the time.js file
...
// use endpoint = /api/time
router.use('/time', TimeRouter );
يتيح لك التوجيه الديناميكي وضع جميع طرقك/مساراتك في ملف وإعلانه في ملف والاتصال بها للاستخدام في أي مكان دون الحاجة إلى إعادة تلاشيه. بمجرد تغيير قيمة المسار ، يتغير في كل مكان.
يتم وضع جميع الطرق والمسارات في /routes/routes-string.js
const api = {
user: {
get: '/:id',
roles: {
get: '/all',
},
register: {
':role': {
save: '/save/:userId?'
}
}
},
bank: {
get: '/all'
}
};
const WEB = {
};
module.exports = {
api,
...WEB
};
...
const resolver = require(process.env.resolver);
// the dynamic routing module is place in the resolver and can be accessed resolver.parser
var $ = resolver.parser;
...
// $('api.bank.get', 'api') returns /api/bank/all as path
router.get($('api.bank.get', 'api'), BankController.getAllBanks);
يتم استخدام Resolver.Parser (المسار ، trimindex) لتحليل فهارس المسار.
Given that our route is -->
{
user: {
get:{
all: '/all'
},
':userId':{
profile: 'profile'
}
}
}
// to formulate user/get/all we will transverse through the index user.get.all
// to formulate user/:userId/profile, transverse through user.:userId.profile
resolver.parser('user.get.all'); // returns /user/get/all
resolver.parser('user.get.all', 'user'); // returns /get/all
resolver.parser('user.get.all', 'user.get'); // returns /all
resolver.parser('user.:userId.profile', {
userId: 3
}); // returns /user/3/profile
لتعيين تفاصيل قاعدة البيانات الخاصة بك ، افتح /.
"DATABASE": {
"USERNAME": "YOUR DATABASE USERNAME",
"PASSWORD": "YOUR DATABASE PASSWORD",
"HOST": "YOUR DATABASE HOST e.g localhost",
"PORT": "YOUR DATABASE PORT e.g 27017",
"NAME": "YOUR DATABASE NAME",
"OPTIONS": {} // extra mongoose options
}
بدلاً من تحديد كل طلب معالجة الطلبات كإغلاق في ملفات الطريق ، قد ترغب في تنظيم هذا السلوك باستخدام كائن وحدة التحكم. يمكن أن تقوم وحدات التحكم بتجميع المنطق معالجة الطلبات في كائن واحد (المصدر: https://laravel.com/docs/5.7/controllers). لإنشاء وحدة تحكم ، قم بإنشاء ملف جديد على سبيل المثال-controller.js في/app/http/controllers. وحدة تحكم نموذجية تبدو هكذا ؛
const resolver = require(process.env.resolver);
const Controller = require('./controller');
var UserController = {};
UserController.getUserRoles = (req, res, next) => {
var returnableRoles = [];
for (var role in Roles)
returnableRoles.push(Roles[role]);
Controller.defaultResponse(res, returnableRoles);
};
module.exports = UserController;
للوصول إلى وحدة التحكم الخاصة بك في أي مكان ، يمكنك بسهولة استخدام Resolver.controllers ("اسم السيطرة الخاصة بك")
...
const resolver = require(process.env.resolver);
const UserController = require(resolver.controllers('user-controller'));
...
router.get('/user/roles', UserController.getUserRoles);
...
توفر البرامج الوسيطة آلية مريحة لتصفية طلبات HTTP التي تدخل تطبيقك. يتم تخزين الأوساط المتوسطة في/APP/HTTP/الوسيطة لإنشاء برامج وسيطة ، إنشاء ملف جديد على eg auth.js في/app/http/middleware. البرامج الوسيطة النموذجية تبدو هكذا ؛
module.exports = (req, res, next) => {
// your logic here
// proceed to next middleware
next();
}
للوصول إلى البرامج الوسيطة في أي مكان ، يمكنك بسهولة استخدام Resolver.middleware ("اسم الأدوات المتوسطة")
...
const resolver = require(process.env.resolver);
const AuthMiddleware= require(resolver.middleware('auth'));
...
router.use('/user', AuthMiddleware);
...
يتم وضع جميع مخطط قاعدة البيانات للمشروع في دليل /قاعدة البيانات /المخطط. مخطط نموذجي يشبه هذا:
const resolver = require(process.env.resolver);
var mongoose = require(resolver.connection());
var lastUpdateDate = require('./plugins/last-update');
var Schema = mongoose.Schema;
// sample for a bank schema
var structure = {};
structure.name = String;
structure.code = String;
var bankSchema = new Schema(structure);
bankSchema.plugin(lastUpdateDate);
module.exports = bankSchema;
يتضمن هذا Boilerplate طريقة بسيطة لبذر قاعدة البيانات الخاصة بك مع بيانات الاختبار باستخدام ملفات البذور. يتم وضع جميع بذور قاعدة البيانات في دليل /قاعدة البيانات /البذور.
const pathResolver = require(process.env.resolver);
const Bank= require(pathResolver.model('bank')).Bank;
var getBanks = () => {
return {
"ACCESS BANK": "044",
"ACCESSMOBILE": "323",
"ASO SAVINGS AND LOANS": "401",
"CELLULANT": "317",
"CENTRAL BANK OF NIGERIA": "001",
"CITIBANK": "023",
"CORONATION MERCHANT BANK": "559",
"CORPORETTI": "310",
"COVENANT MICROFINANCE BANK": "551",
"DIAMOND BANK": "063",
"EARTHOLEUM(QIK QIK)": "302",
"ECOBANK NIGERIA": "050",
"ECOMOBILE": "307",
"EKONDO MICROFINANCE BANK": "562",
"ENTERPRISE BANK": "084",
"EQUITORIAL TRUST BANK": "040",
"E - TRANZACT": "306",
"FBN M- MONEY": "309",
"FBN MORTGAGES": "413",
"FETS(MY WALLET)": "314",
"FIDELITY BANK": "070",
"FIDELITY MOBILE": "318",
"FINATRUST MICROFINANCE BANK": "608",
"FIRST BANK OF NIGERIA": "011",
"FIRST CITY MONUMENT BANK": "214",
"FIRST INLAND BANK": "085",
"FORTIS MICROFINANCE BANK": "501",
"FORTIS MOBILE": "308",
"FSDH": "601",
"GT MOBILE MONEY": "315",
"GUARANTY TRUST BANK": "058",
"HEDONMARK": "324",
"HERITAGE BANK": "030",
"IMPERIAL HOMES MORTGAGE BANK": "415",
"INTERCONTINENTAL BANK": "069",
"JAIZ BANK": "301",
"JUBILEE LIFE": "402",
"KEGOW": "303",
"KEYSTONE BANK": "082",
"MAINSTREET BANK": "014",
"MIMONEY(POWERED BY INTELLIFIN)": "330",
"M - KUDI": "313",
"MONETIZE": "312",
"MONEYBOX": "325",
"NEW PRUDENTIAL BANK": "561",
"NPF MFB": "552",
"OCEANIC BANK": "056",
"OMOLUABI SAVINGS AND LOANS": "606",
"ONE FINANCE": "565",
"PAGA": "327",
"PAGE MFBANK": "560",
"PARALLEX": "502",
"PARKWAY(READY CASH)": "311",
"PAYATTITUDE ONLINE": "329",
"PAYCOM": "304",
"PROVIDUS BANK": "101",
"SAFETRUST MORTGAGE BANK": "403",
"SEED CAPITAL MICROFINANCE BANK": "609",
"SKYE BANK": "076",
"STANBIC IBTC BANK": "221",
"STANBIC MOBILE": "304",
"STANDARD CHARTERED BANK": "068",
"STERLING BANK": "232",
"STERLING MOBILE": "326",
"SUNTRUST": "100",
"TEASY MOBILE": "319",
"TRUSTBOND": "523",
"U - MO": "316",
"UNION BANK OF NIGERIA": "032",
"UNITED BANK FOR AFRICA": "033",
"UNITY BANK": "215",
"VFD MICROFINANCE BANK": "566",
"VISUAL ICT": "328",
"VTNETWORK": "320",
"WEMA BANK": "035",
"ZENITH BANK": "057",
"ZENITH MOBILE": "322"
};
};
var locationSeed = () => {
// get all banks
banks = getBanks();
var insertables = [];
for (var name in banks) {
var code = banks[name];
insertables.push({
name,
code
});
}
Bank.insertMany(insertables, (err, docs) => {
if (err) {
console.error(err);
}
});
};
module.exports = locationSeed;
بعد وضع البذور في دليل البذور ، يجب عليك تحديدها في /database/all-eseds.js لتمكين البذور من تحديد موقعه
var SeedBanks= require('./seeds/banks');
var exports = {
SeedBanks,
// place your seeds here
};
module.exports = exports;
لترحيل البذور الخاصة بك ، يمكنك استخدام أمر Bellow.
> node cmd run:seed
هذا يمكّنك من تشغيل أوامر معينة في واجهة سطر الأوامر).
لإنشاء أمر مخصص ؛ قم بإنشاء ملف يستضيف المنطق إلى أمرك في /الأوامر على سبيل المثال /commands/remove-users.js يمكن أن يحتوي على المقتطف أدناه
var exports = {};
exports.removeOldUsers = (args) => {
// logic here
};
module.exports = exports;
ثم حدد اسم الأمر الخاص بك وأيضًا وظيفة قابلة للاتصال في /Commands/index.js
var seeder = require('./seed');
/**
* @info all arguments are to be placed here
*/
const arguments = {
'run:seed': seeder.runSeed,
'your_command': CallableFunction
};
module.exports = arguments;
يتيح لك ذلك التحقق من صحة قيمة معينة مقابل مجموعة من القواعد.
// Use this to import validation module
var resolver = require(process.env.resolver);
var validator = require(resolver.validator());
يتم التحقق من صحة بشكل غير متزامن. المدقق (array_of_rules ، رد الاتصال) ؛
validator([
{
fieldName: "name", // name of the field
fieldValue: 2, // the value of the field
validation: 'min:3|max:4', // set of validation rules
errorMessage:"Invalid name" // custom error message for all rules.
}
], (result) => {
res.send(result);
res.end();
});
تتضمن القواعد المسموح بها:
يتحقق هذا من أن قيمة العطاء هي ذات الحد الأدنى للطول أو قيمة القيمة المحددة. على سبيل المثال: 2 ، يتحقق من أن السلسلة لديها الحد الأدنى من حرفين وفي حالة كونها عددية ، فإنها تتحقق من أن الرقم المعطى أكبر من أو يساوي 2.
يتحقق هذا من أن قيمة العطاء هي ذات طول أو قيمة للقيمة المحددة. على سبيل المثال: 2 ، يتحقق من أن السلسلة لديها أقصى طول من حرفين وفي حالة كونها عددية ، فإنها تتحقق من أن الرقم المعطى أقل من أو يساوي 2.
هذا يتحقق من أن القيمة المعطاة تحتوي فقط على أحرف أبجدية ولا شيء آخر.
هذا يتحقق من أن القيمة المعطاة تحتوي فقط على أحرف ألفا رقمية ولا شيء آخر.
هذا يؤكد أن القيمة المحددة هي مجموعة من العناصر.
هذا يؤكد أن القيمة المحددة هي رقم عشري
هذا يتحقق من أن القيمة المحددة هي بريد إلكتروني صالح.
هذا يتحقق من أن القيمة المحددة تحتوي على قيم عددية فقط.
يتحقق هذا ما إذا كانت القيمة المحددة رقم هاتف صالح.
هذا يتحقق من أن القيمة المحددة ليست فارغة.
للتحقق مما إذا فشل التحقق من الصحة
validator(rules, (result) => {
result.failed(); // returns a boolean. true when it fails and false when it doesnt.
result.getFirst('field name'); // returns the first error for the field and undefined in case there is no error
result.getError('field name'); // returns all errors for the field
});
لم يتم تضمين اختبار الوحدة في هذا الغلاية. ومع ذلك ، يمكنك اختيار تضمينه بنفسك.
أي شخص وكل شخص مرحب به للمساهمة.
معهد ماساتشوستس للتكنولوجيا