Um aplicativo de caldeira para criar aplicativos da Web usando o Express e o 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
O resolvedor contém uma lista de módulos que podem ajudar em vários aspectos.
// how to access the resolver
var resolver = require(process.env.resolver);
Usado para analisar strings de rota e objeto
resolver.parser(urlSelector, urlParameters, skipBackSlash);
Retorna uma sequência de caminho em relação ao diretório raiz.
resolver.router('database/all-seeds'); // returns __ROOT_DIRECTORY__/database/all-seeds
Retorna o caminho para o módulo de conexão DB.
const resolver = require(process.env.resolver);
var mongoose = require(resolver.connection());
mongoose.model('User', UserSchema);
Retorna o caminho para o arquivo de modelo passado como parâmetro
const resolver = require(process.env.resolver);
var bankModelPath = pathResolver.model('bank');
const Bank = require(bankModelPath);
Retorna o caminho para o arquivo de esquema de banco de dados passado como parâmetro
const resolver = require(process.env.resolver);
var bankSchemaPath = resolver.dbSchema('bank');
const BankSchema = require(bankSchemaPath);
var Bank = mongoose.model('Bank', BankSchema);
Retorna o caminho para o arquivo do controlador passado 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)=>{ });
Retorna o caminho para o arquivo de middleware passado como parâmetro
const resolver = require(process.env.resolver);
var authMiddlewarePath= resolver.middleware('auth');
const AuthMiddleware= require(authMiddlewarePath);
app.use('/user', AuthMiddleware);
Todas as rotas estão contidas no Project_Directory /rotas e estão anexadas /mapeadas ao roteador base que está contido em /routtes/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, você deseja criar um endpoint da API para que as pessoas obtenham o horário do servidor atual em um arquivo separado (time.js que conterá todos os pontos de extremidade relacionados ao tempo).
Criar e abrir /Routes/API/time.js. Então o conteúdo deve parecer:
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 );
O roteamento dinâmico permite que você coloque e declare todas as suas rotas/caminhos em um arquivo e ligue para usá-los em qualquer lugar sem a necessidade de redigir-o. Depois de alterar o valor de uma rota, ele muda em todos os lugares em que é usado.
Todas as rotas e caminhos são colocados em /routes/Routes-tring.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);
O Resolver.Parser (Path, Trimindex) é usado para analisar os índices de uma rota.
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 definir os detalhes do seu banco de dados, abra o arquivo /.env e atualize o conteúdo da seguinte forma:
"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
}
Em vez de definir todas as suas solicitações de lógica de manuseio como fechamento em arquivos de rota, você pode organizar esse comportamento usando o objeto Controller. Os controladores podem agrupar a lógica de manuseio de solicitações relacionadas em um único objeto (fonte: https://laravel.com/docs/5.7/controllers). Para criar um controlador, crie um novo arquivo, por exemplo, controlador de usuário.js in/app/http/controladores. Um controlador típico se parece com isso;
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 acessar seu controlador em qualquer lugar, você pode usar facilmente o resolver.Controllers ('Nome-de-seu controlador')
...
const resolver = require(process.env.resolver);
const UserController = require(resolver.controllers('user-controller'));
...
router.get('/user/roles', UserController.getUserRoles);
...
O Middleware fornece um mecanismo conveniente para filtrar solicitações HTTP inserindo seu aplicativo. Middlewares são armazenados em/app/http/middleware para criar um middleware, criar um novo arquivo, por exemplo, auth.js in/app/http/middleware. Um middleware típico se parece com isso;
module.exports = (req, res, next) => {
// your logic here
// proceed to next middleware
next();
}
Para acessar seu middleware em qualquer lugar, você pode usar facilmente o resolver.middleware ('Nome-de-seu-Middleware')
...
const resolver = require(process.env.resolver);
const AuthMiddleware= require(resolver.middleware('auth'));
...
router.use('/user', AuthMiddleware);
...
Todo o esquema de banco de dados para o projeto é colocado no diretório /banco de dados /esquema. Um esquema típico se parece com o seguinte:
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;
Este caldeira inclui um método simples de semear seu banco de dados com dados de teste usando arquivos de semente. Todas as sementes de banco de dados são colocadas no diretório /banco de dados /sementes.
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;
Depois de colocar sua semente no diretório de sementes, você deve especificá-la em /database/all-seeds.js para permitir que a semente a localize
var SeedBanks= require('./seeds/banks');
var exports = {
SeedBanks,
// place your seeds here
};
module.exports = exports;
Para migrar suas sementes, você usa o comando bellow.
> node cmd run:seed
Isso permite que você execute certos comandos na CLI (interface da linha de comando).
Para criar seu comando personalizado; Crie um arquivo que hospede a lógica ao seu comando em /comandos , por exemplo, /commands/remove-users.js poderia conter o trecho abaixo
var exports = {};
exports.removeOldUsers = (args) => {
// logic here
};
module.exports = exports;
Em seguida, especifique o nome do seu comando e também uma função chamada em /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;
Isso permite que você valide um determinado valor contra algum conjunto de regras.
// Use this to import validation module
var resolver = require(process.env.resolver);
var validator = require(resolver.validator());
As validações são feitas de forma assíncrona. validator (array_of_rules, retorno de chamada);
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();
});
As regras permitidas incluem:
Isso verifica se o valor de doação é de comprimento ou valor mínimo do valor especificado. Por exemplo, Min: 2, verifica se a string tem um comprimento mínimo de 2 caracteres e, caso seja numérico, verifica se o número fornecido é maior ou igual a 2.
Isso verifica se o valor de doação é de comprimento ou valor máximo do valor especificado. Por exemplo, Min: 2, verifica se a string tem um comprimento máximo de 2 caracteres e, caso seja numérico, verifica se o número fornecido é menor que ou igual a 2.
Isso verifica se o valor fornecido contém apenas caracteres alfabéticos e nada mais.
Isso verifica se o valor fornecido contém apenas caracteres numéricos alfa e nada mais.
Isso confirma que o valor fornecido é uma variedade de itens.
Isso confirma que o valor fornecido é um número decimal
Isso valida que o valor fornecido é um email válido.
Isso valida que o valor fornecido contém apenas valores numéricos.
Isso verifica se o valor fornecido é um número de telefone válido.
Isso verifica se o valor fornecido não está vazio.
Para verificar se uma validação falhou
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
});
O teste de unidade não foi incluído neste caldeira. No entanto, você pode optar por incluí -lo por conta própria.
Qualquer um e todo mundo pode contribuir.
Mit