Eine Boilerplate -Anwendung zum Erstellen von Web -Apps mit Express und 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
Der Resolver enthält eine Liste von Modulen, die in verschiedenen Aspekten helfen können.
// how to access the resolver
var resolver = require(process.env.resolver);
Wird zum Parsen von Routenzeichenfolgen und zum Objekt verwendet
resolver.parser(urlSelector, urlParameters, skipBackSlash);
Gibt eine Reihe von Pfad relativ zum Stammverzeichnis zurück.
resolver.router('database/all-seeds'); // returns __ROOT_DIRECTORY__/database/all-seeds
Gibt den Pfad zum DB -Verbindungsmodul zurück.
const resolver = require(process.env.resolver);
var mongoose = require(resolver.connection());
mongoose.model('User', UserSchema);
Gibt den Pfad in die als Parameter übergebene Modelldatei zurück
const resolver = require(process.env.resolver);
var bankModelPath = pathResolver.model('bank');
const Bank = require(bankModelPath);
Gibt den Pfad an die Datenbankschema -Datei zurück als Parameter übergeben
const resolver = require(process.env.resolver);
var bankSchemaPath = resolver.dbSchema('bank');
const BankSchema = require(bankSchemaPath);
var Bank = mongoose.model('Bank', BankSchema);
Gibt den Pfad an die Controller -Datei zurück als Parameter übergeben
const resolver = require(process.env.resolver);
var userControllerPath = resolver.controllers('user-controller');
const UserController= require(userControllerPath);
UserController.deleteUser(user_id, (err, response)=>{ });
Gibt den Pfad an die Middleware -Datei zurück als Parameter übergeben
const resolver = require(process.env.resolver);
var authMiddlewarePath= resolver.middleware('auth');
const AuthMiddleware= require(authMiddlewarePath);
app.use('/user', AuthMiddleware);
Alle Routen sind in den Project_Directory /Routen enthalten und sind an den Basisrouter angehängt /zugeordnet
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);
};
Angenommen, Sie möchten einen API -Endpunkt für Personen erstellen, um die aktuelle Serverzeit in einer separaten Datei zu erhalten (Time.js, die alle Endpunkte in Bezug auf die Zeit enthalten).
Erstellen und öffnen /routes/api/time.js. Dann sollte der Inhalt so aussehen:
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 );
Mit dynamischem Routing können Sie alle Ihre Routen/Pfade in einer Datei platzieren und deklarieren, und rufen Sie sie an, um sie überall zu verwenden, ohne sie neu zu deklarieren. Sobald Sie den Wert einer Route ändern, ändert sich sie überall, wo sie verwendet wird.
Alle Routen und Pfade werden in /routes/routes-string.js platziert
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 (Pfad, TrimIndex) wird verwendet, um die Indizes einer Route zu analysieren.
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
Öffnen Sie /.env -Datei, um Ihre Datenbankdetails festzulegen und den Inhalt wie folgt zu aktualisieren:
"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
}
Anstatt alle Ihre Anforderungslogik als Verschluss in Routendateien zu definieren, möchten Sie dieses Verhalten möglicherweise mithilfe des Controller -Objekts organisieren. Controller können zu einer Logik der Anforderung zu einem einzigen Objekt gruppieren (Quelle: https://laravel.com/docs/5.7/controllers). Um einen Controller zu erstellen, erstellen Sie eine neue Datei EG User-Controller.js in/app/http/Controller. Ein typischer Controller sieht so aus;
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;
Um überall auf Ihren Controller zuzugreifen, können Sie problemlos Resolver.Controller ('Name-of-your-Controller') verwenden.
...
const resolver = require(process.env.resolver);
const UserController = require(resolver.controllers('user-controller'));
...
router.get('/user/roles', UserController.getUserRoles);
...
Middleware bietet einen bequemen Mechanismus für die Filterung von HTTP -Anfragen, die in Ihre Anwendung eintreten. MiddleWares werden in/app/http/Middleware gespeichert, um eine Middleware zu erstellen. Erstellen Sie eine neue Datei EG Auth.js in/App/HTTP/Middleware. Eine typische Middleware sieht so aus.
module.exports = (req, res, next) => {
// your logic here
// proceed to next middleware
next();
}
Um überall auf Ihre Middleware zugreifen zu können, können Sie problemlos Resolver.middleware ('Name-of-your-Middleware') verwenden.
...
const resolver = require(process.env.resolver);
const AuthMiddleware= require(resolver.middleware('auth'));
...
router.use('/user', AuthMiddleware);
...
Das gesamte Datenbankschema für das Projekt wird im Verzeichnis /Datenbank /Schema platziert. Ein typisches Schema sieht so aus:
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;
Diese Kesselplatte enthält eine einfache Methode, um Ihre Datenbank mit Testdaten mit Saatgutdateien zu säen. Alle Datenbanksamen werden in /Datenbank /Seeds -Verzeichnis platziert.
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;
Nachdem Sie Ihr Samen in das Samenverzeichnis eingerichtet haben, müssen Sie es in /database/all-seeds.js angeben, damit der Säator es lokalisiert hat
var SeedBanks= require('./seeds/banks');
var exports = {
SeedBanks,
// place your seeds here
};
module.exports = exports;
Um Ihre Samen zu migrieren, verwenden Sie den Befehl bellow.
> node cmd run:seed
Dadurch können Sie bestimmte Befehle in der CLI (Befehlszeilenschnittstelle) ausführen.
Um Ihren benutzerdefinierten Befehl zu erstellen; Erstellen Sie eine Datei, die die Logik in Ihrem Befehl in /Befehls EG /commands/remove-users.js hostet.
var exports = {};
exports.removeOldUsers = (args) => {
// logic here
};
module.exports = exports;
Geben Sie dann Ihren Befehlsnamen und auch eine aufrufbare Funktion in /commands/index.js an
var seeder = require('./seed');
/**
* @info all arguments are to be placed here
*/
const arguments = {
'run:seed': seeder.runSeed,
'your_command': CallableFunction
};
module.exports = arguments;
Auf diese Weise können Sie einen bestimmten Wert gegen einige Regeln validieren.
// Use this to import validation module
var resolver = require(process.env.resolver);
var validator = require(resolver.validator());
Validierungen werden asynchron durchgeführt. Validator (Array_of_RULES, Rückruf);
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();
});
Die zulässigen Regeln umfassen:
Dies prüft, dass der Wertschöpfungswert minimale Länge oder Wert des angegebenen Werts hat. ZB min: 2 prüft, dass die Zeichenfolge eine Mindestlänge von 2 Zeichen hat, und falls sie numerisch ist, prüft sie, dass die angegebene Zahl größer ist als oder gleich 2.
Dies prüft, dass der Wert der angebenen Wert von maximaler Länge oder Wert des angegebenen Wertes ist. ZB min: 2 prüft, dass die Zeichenfolge eine maximale Länge von 2 Zeichen hat und falls sie numerisch ist, überprüft, dass die angegebene Zahl kleiner als oder gleich 2 ist.
Dies prüft, dass der angegebene Wert nur alphabetische Zeichen und sonst nichts enthält.
Dies prüft, dass der angegebene Wert nur Alpha -numerische Zeichen und sonst nichts enthält.
Dies bestätigt, dass der angegebene Wert eine Reihe von Elementen ist.
Dies bestätigt, dass der angegebene Wert eine Dezimalzahl ist
Dies bestätigt, dass der angegebene Wert eine gültige E -Mail ist.
Dies bestätigt, dass der angegebene Wert nur numerische Werte enthält.
Dies prüft, ob der angegebene Wert eine gültige Telefonnummer ist.
Dies prüft, ob der angegebene Wert nicht leer ist.
Um zu überprüfen, ob eine Validierung fehlgeschlagen ist
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
});
In dieser Kesselplatte wurden keine Unit -Tests enthalten. Sie können es jedoch selbst einschließen.
Jeder und jeder ist eingeladen, einen Beitrag zu leisten.
MIT