Una aplicación Boilerplate para crear aplicaciones web que usan Express y 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
El resolución contiene una lista de módulos que pueden ayudar en varios aspectos.
// how to access the resolver
var resolver = require(process.env.resolver);
Utilizado para analizar cadenas de ruta y objeto
resolver.parser(urlSelector, urlParameters, skipBackSlash);
Devuelve una cadena de ruta relativa al directorio raíz.
resolver.router('database/all-seeds'); // returns __ROOT_DIRECTORY__/database/all-seeds
Devuelve la ruta al módulo de conexión DB.
const resolver = require(process.env.resolver);
var mongoose = require(resolver.connection());
mongoose.model('User', UserSchema);
Devuelve la ruta al archivo del modelo aprobado como parámetro
const resolver = require(process.env.resolver);
var bankModelPath = pathResolver.model('bank');
const Bank = require(bankModelPath);
Devuelve la ruta al archivo de esquema de la base de datos pasada como parámetro
const resolver = require(process.env.resolver);
var bankSchemaPath = resolver.dbSchema('bank');
const BankSchema = require(bankSchemaPath);
var Bank = mongoose.model('Bank', BankSchema);
Devuelve la ruta al archivo del controlador aprobado como parámetro
const resolver = require(process.env.resolver);
var userControllerPath = resolver.controllers('user-controller');
const UserController= require(userControllerPath);
UserController.deleteUser(user_id, (err, response)=>{ });
Devuelve la ruta al archivo de middleware aprobado como parámetro
const resolver = require(process.env.resolver);
var authMiddlewarePath= resolver.middleware('auth');
const AuthMiddleware= require(authMiddlewarePath);
app.use('/user', AuthMiddleware);
Todas las rutas están contenidas en el proyecto_directory /rutas y están conectadas /asignadas al enrutador base que está contenido en /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);
};
Digamos, desea crear un punto final API para que las personas obtengan el tiempo del servidor actual en un archivo separado (Time.js que contendrá todos los puntos finales relacionados con el tiempo).
Crear y abrir /Routes/api/time.js. Entonces el contenido debería verse como:
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 );
El enrutamiento dinámico le permite colocar y declarar todas sus rutas/rutas en un archivo y llamarlos para usarlos en cualquier lugar sin necesidad de volver a decidirlo. Una vez que cambia el valor de una ruta, cambia en todas partes se usa.
Todas las rutas y rutas se colocan en /Routes/RoutesString.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 (ruta, trimindex) se usa para analizar los índices de una ruta.
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
Para establecer los detalles de su base de datos, abrir el archivo /.env y actualizar el contenido de la siguiente manera:
"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
}
En lugar de definir todas sus solicitudes de manejo de lógica como cierres en los archivos de ruta, es posible que desee organizar este comportamiento utilizando el objeto controlador. Los controladores pueden agrupar la lógica de manejo de solicitudes relacionadas en un solo objeto (fuente: https://laravel.com/docs/5.7/controllers). Para crear un controlador, cree un nuevo archivo, por ejemplo, user-Controller.js in/app/http/controladores. Un controlador típico se ve así;
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;
Para acceder a su controlador en cualquier lugar, puede usar fácilmente resolver.controllers ('nombre de tu controlador')
...
const resolver = require(process.env.resolver);
const UserController = require(resolver.controllers('user-controller'));
...
router.get('/user/roles', UserController.getUserRoles);
...
El middleware proporciona un mecanismo conveniente para filtrar solicitudes HTTP que ingresan a su aplicación. MiddleWares se almacenan en/App/Http/Middleware para crear un middleware, cree un nuevo archivo, por ejemplo, Auth.js in/App/Http/Middleware. Un middleware típico se ve así;
module.exports = (req, res, next) => {
// your logic here
// proceed to next middleware
next();
}
Para acceder a su middleware en cualquier lugar, puede usar fácilmente resolución.
...
const resolver = require(process.env.resolver);
const AuthMiddleware= require(resolver.middleware('auth'));
...
router.use('/user', AuthMiddleware);
...
Todo el esquema de la base de datos para el proyecto se coloca en el directorio de /base de datos /esquema. Un esquema típico se ve así:
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;
Esta calderera incluye un método simple para sembrar su base de datos con datos de prueba utilizando archivos de semillas. Todas las semillas de base de datos se colocan en el directorio de /base de datos /semillas.
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;
Después de colocar su semilla en el directorio de semillas, debe especificarla en /database/all-seeds.js para permitir que la sembradora la ubique
var SeedBanks= require('./seeds/banks');
var exports = {
SeedBanks,
// place your seeds here
};
module.exports = exports;
Para migrar sus semillas, entonces usa el comando Bellow.
> node cmd run:seed
Esto le permite ejecutar ciertos comandos en la CLI (interfaz de línea de comandos).
Para crear su comando personalizado; Cree un archivo que aloje la lógica en su comando en /comandos EG /Commands/Remove-Users.js podría contener el fragmento a continuación
var exports = {};
exports.removeOldUsers = (args) => {
// logic here
};
module.exports = exports;
Luego especifique el nombre de su comando y también una función invocable en /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;
Esto le permite validar un valor dado en algún conjunto de reglas.
// Use this to import validation module
var resolver = require(process.env.resolver);
var validator = require(resolver.validator());
Las validaciones se realizan de manera asincrónica. Validator (array_of_rules, devolución de llamada);
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();
});
Las reglas permitidas incluyen:
Esto verifica que el valor de donación es de longitud o valor mínimo del valor especificado. Por ejemplo, 2, verifica que la cadena tiene una longitud mínima de 2 caracteres y, en caso de que sea numérico, verifica que el número dado es mayor o es igual a 2.
Esto verifica que el valor de donación es de longitud o valor máximo del valor especificado. Por ejemplo, 2, verifica que la cadena tiene una longitud máxima de 2 caracteres y, en caso de que sea numérico, verifica que el número dado es menor o es igual a 2.
Esto verifica que el valor dado solo contiene caracteres alfabéticos y nada más.
Esto verifica que el valor dado solo contiene caracteres numéricos alfa y nada más.
Esto confirma que el valor dado es una variedad de elementos.
Esto confirma que el valor dado es un número decimal
Esto valida que el valor dado es un correo electrónico válido.
Esto valida que el valor dado contiene solo valores numéricos.
Esto verifica si el valor dado es un número de teléfono válido.
Esto verifica que el valor dado no está vacío.
Para verificar si una validación falló
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
});
Las pruebas unitarias no se han incluido en esta caldera. Sin embargo, puede elegir incluirlo por su cuenta.
Cualquiera y todos pueden contribuir.
MIT