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
리졸버에는 다양한 측면에서 도움이 될 수있는 모듈 목록이 포함되어 있습니다.
// 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 /loutes에 포함되어 있으며 /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);
};
사람들이 현재 서버 시간을 별도의 파일 (시간과 관련된 모든 엔드 포인트를 포함하는 time.js)에서 API 엔드 포인트를 작성하려고합니다.
/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 (Path, 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
데이터베이스 세부 정보를 설정하려면 /.env 파일을 열고 다음과 같이 컨텐츠를 업데이트하십시오.
"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). 컨트롤러를 만들려면 새 파일을 만듭니다. 즉, us user-controller.js in/app/http/컨트롤러를 작성하십시오. 일반적인 컨트롤러는 다음과 같습니다.
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 ( 'Controller 이름')를 쉽게 사용할 수 있습니다.
...
const resolver = require(process.env.resolver);
const UserController = require(resolver.controllers('user-controller'));
...
router.get('/user/roles', UserController.getUserRoles);
...
Middleware는 응용 프로그램을 입력하는 HTTP 요청을 필터링하기위한 편리한 메커니즘을 제공합니다. 중간 전위는/app/http/middleware에 저장되어 미들웨어를 만들고/app/http/middleware in aug.js 예를 들어 새 파일을 만듭니다. 전형적인 미들웨어는 다음과 같습니다.
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;
이 보일러 플레이트에는 종자 파일을 사용하여 테스트 데이터로 데이터베이스를 시드하는 간단한 방법이 포함되어 있습니다. 모든 데이터베이스 씨앗은 /데이터베이스 /시드 디렉토리에 배치됩니다.
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-seeds.js에 지정해야합니다.
var SeedBanks= require('./seeds/banks');
var exports = {
SeedBanks,
// place your seeds here
};
module.exports = exports;
씨앗을 마이그레이션하려면 Bellow 명령을 사용합니다.
> node cmd run:seed
이를 통해 CLI (명령 줄 인터페이스)에서 특정 명령을 실행할 수 있습니다.
사용자 정의 명령을 만들려면; /명령 에 대한 명령에 논리를 호스팅하는 파일을 만듭니다.
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());
유효성 검사는 비동기 적으로 수행됩니다. 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, 문자열의 최대 길이가 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
});
이 보일러 플레이트에는 단위 테스트가 포함되지 않았습니다. 그러나 직접 포함하도록 선택할 수 있습니다.
누구나 모든 사람이 기여할 수 있습니다.
MIT