Aplikasi boilerplate untuk membangun aplikasi web menggunakan Express, dan 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 berisi daftar modul yang dapat membantu dalam berbagai aspek.
// how to access the resolver
var resolver = require(process.env.resolver);
Digunakan untuk string dan objek rute parsing
resolver.parser(urlSelector, urlParameters, skipBackSlash);
Mengembalikan serangkaian jalur relatif ke direktori root.
resolver.router('database/all-seeds'); // returns __ROOT_DIRECTORY__/database/all-seeds
Mengembalikan jalur ke modul koneksi DB.
const resolver = require(process.env.resolver);
var mongoose = require(resolver.connection());
mongoose.model('User', UserSchema);
Mengembalikan jalur ke file model yang dilewati sebagai parameter
const resolver = require(process.env.resolver);
var bankModelPath = pathResolver.model('bank');
const Bank = require(bankModelPath);
Mengembalikan jalur ke file skema database yang dilewati sebagai parameter
const resolver = require(process.env.resolver);
var bankSchemaPath = resolver.dbSchema('bank');
const BankSchema = require(bankSchemaPath);
var Bank = mongoose.model('Bank', BankSchema);
Mengembalikan jalur ke file pengontrol yang dilewati sebagai parameter
const resolver = require(process.env.resolver);
var userControllerPath = resolver.controllers('user-controller');
const UserController= require(userControllerPath);
UserController.deleteUser(user_id, (err, response)=>{ });
Mengembalikan jalur ke file middleware yang dilewati sebagai parameter
const resolver = require(process.env.resolver);
var authMiddlewarePath= resolver.middleware('auth');
const AuthMiddleware= require(authMiddlewarePath);
app.use('/user', AuthMiddleware);
Semua rute terkandung dalam proyek_direktori /rute dan dilampirkan /dipetakan ke router dasar yang terkandung dalam /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);
};
Katakanlah, Anda ingin membuat titik akhir API untuk orang -orang untuk mendapatkan waktu server saat ini dalam file terpisah (Time.js yang akan berisi semua titik akhir yang berkaitan dengan waktu).
Buat dan buka /Routes/api/time.js. maka kontennya seharusnya terlihat seperti:
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 );
Routing dinamis memungkinkan Anda untuk menempatkan dan mendeklarasikan semua rute/jalur Anda dalam file dan memanggilnya untuk digunakan di mana saja tanpa perlu mendeklarasikan kembali. Setelah Anda mengubah nilai rute, itu berubah di mana pun itu digunakan.
Semua rute & jalur ditempatkan di /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 (Path, trimIndex) digunakan untuk menguraikan indeks rute.
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
Untuk mengatur detail database Anda, buka /.env file, dan perbarui konten sebagai berikut:
"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
}
Alih -alih mendefinisikan semua logika penanganan permintaan Anda sebagai penutupan dalam file rute, Anda mungkin ingin mengatur perilaku ini menggunakan objek pengontrol. Pengontrol dapat mengelompokkan permintaan penanganan permintaan terkait ke dalam satu objek (sumber: https://laravel.com/docs/5.7/controllers). Untuk membuat pengontrol, buat file baru misalnya pengguna-controller.js di/app/http/controllers. Pengontrol khas terlihat seperti ini;
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;
Untuk mengakses controller Anda di mana saja, Anda dapat dengan mudah menggunakan resolver.controllers ('nama-pengontrol Anda')
...
const resolver = require(process.env.resolver);
const UserController = require(resolver.controllers('user-controller'));
...
router.get('/user/roles', UserController.getUserRoles);
...
Middleware menyediakan mekanisme yang nyaman untuk memfilter permintaan HTTP yang memasukkan aplikasi Anda. Middlewares disimpan di/app/http/middleware untuk membuat middleware, membuat file baru misalnya auth.js di/app/http/middleware. Middleware khas terlihat seperti ini;
module.exports = (req, res, next) => {
// your logic here
// proceed to next middleware
next();
}
Untuk mengakses middleware Anda di mana saja, Anda dapat dengan mudah menggunakan resolver.middleware ('nama-middleware Anda')
...
const resolver = require(process.env.resolver);
const AuthMiddleware= require(resolver.middleware('auth'));
...
router.use('/user', AuthMiddleware);
...
Semua skema basis data untuk proyek ditempatkan di /direktori database /skema. Skema khas terlihat seperti ini:
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 ini mencakup metode sederhana untuk menyemai database Anda dengan data uji menggunakan file benih. Semua biji basis data ditempatkan di /direktori basis data /biji.
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;
Setelah menempatkan benih Anda di direktori benih, Anda harus menentukannya di /database/all-seeds.js untuk memungkinkan seeder menemukannya
var SeedBanks= require('./seeds/banks');
var exports = {
SeedBanks,
// place your seeds here
};
module.exports = exports;
Untuk memigrasikan benih Anda, maka Anda menggunakan perintah Bellow.
> node cmd run:seed
Ini memungkinkan Anda untuk menjalankan perintah tertentu di CLI (antarmuka baris perintah).
Untuk membuat perintah khusus Anda; Buat file yang meng-host logika ke perintah Anda di /perintah misal /commands/remove-users.js dapat berisi cuplikan di bawah ini
var exports = {};
exports.removeOldUsers = (args) => {
// logic here
};
module.exports = exports;
Kemudian tentukan nama perintah Anda dan juga fungsi yang dapat dipanggil di /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;
Ini memungkinkan Anda untuk memvalidasi nilai yang diberikan terhadap beberapa set aturan.
// Use this to import validation module
var resolver = require(process.env.resolver);
var validator = require(resolver.validator());
Validasi dilakukan secara tidak sinkron. validator (array_of_rules, callback);
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();
});
Aturan yang diizinkan meliputi:
Ini memeriksa bahwa nilai pemberian memiliki panjang atau nilai minimum dari nilai yang ditentukan. misalnya min: 2, memeriksa bahwa string memiliki panjang minimum 2 karakter dan jika numerik, ia memeriksa bahwa angka yang diberikan lebih besar dari atau sama dengan 2.
Ini memeriksa bahwa nilai pemberian memiliki panjang atau nilai maksimum dari nilai yang ditentukan. misalnya min: 2, memeriksa bahwa string memiliki panjang maksimum 2 karakter dan jika numerik, ia memeriksa bahwa angka yang diberikan kurang dari atau sama dengan 2.
Ini memeriksa bahwa nilai yang diberikan hanya berisi karakter alfabet dan tidak ada yang lain.
Ini memeriksa bahwa nilai yang diberikan hanya berisi karakter numerik alpha dan tidak ada yang lain.
Ini menegaskan bahwa nilai yang diberikan adalah array item.
Ini menegaskan bahwa nilai yang diberikan adalah angka desimal
Ini memvalidasi bahwa nilai yang diberikan adalah email yang valid.
Ini memvalidasi bahwa nilai yang diberikan hanya berisi nilai numerik.
Ini memeriksa apakah nilai yang diberikan adalah nomor telepon yang valid.
Ini memeriksa bahwa nilai yang diberikan tidak kosong.
Untuk memeriksa apakah validasi gagal
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
});
Pengujian unit belum dimasukkan dalam boilerplate ini. Namun, Anda dapat memilih untuk memasukkannya sendiri.
Siapa pun dan semua orang dipersilakan untuk berkontribusi.
Mit