├── .env.example ├── views ├── layout │ ├── footer.ejs │ └── header.ejs ├── 404.ejs └── index.ejs ├── routes └── test.js ├── .vscode └── settings.json ├── README.md ├── config ├── index.js └── db.js ├── .prettierrc.json ├── controllers ├── error.js └── swaggerTest.js ├── middlewares └── fileUpload.js ├── .eslintrc.json ├── models └── test.js ├── package.json ├── index.js └── .gitignore /.env.example: -------------------------------------------------------------------------------- 1 | SERVER_PORT=3000 2 | DB_URL=mongodb://127.0.0.1:27017/testDatabase 3 | -------------------------------------------------------------------------------- /views/layout/footer.ejs: -------------------------------------------------------------------------------- 1 | 4 | 5 | -------------------------------------------------------------------------------- /views/404.ejs: -------------------------------------------------------------------------------- 1 | <%-include("./layout/header.ejs")%> 2 |

404 Not Found

3 | <%-include("./layout/footer.ejs")%> 4 | -------------------------------------------------------------------------------- /routes/test.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | 3 | const testRoute = express(); 4 | 5 | module.exports = testRoute; 6 | -------------------------------------------------------------------------------- /views/index.ejs: -------------------------------------------------------------------------------- 1 | <%-include("./layout/header.ejs")%> 2 |

Welcome to the server

3 | <%-include("./layout/footer.ejs")%> 4 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.defaultFormatter": "esbenp.prettier-vscode", 3 | "editor.formatOnSave": true, 4 | "editor.formatOnPaste": true 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Basic Express, Mongoose, Swagger setup 2 | 3 | ## setup the project 4 | 5 | ### step 1: clone the project 6 | 7 | ### step 2: npm install 8 | 9 | ### step 3: setup .env variable 10 | -------------------------------------------------------------------------------- /config/index.js: -------------------------------------------------------------------------------- 1 | require("dotenv").config(); 2 | 3 | exports.dev = { 4 | db: { 5 | url: process.env.DB_URL || "", 6 | }, 7 | app: { 8 | port: process.env.SERVER_PORT, 9 | }, 10 | }; 11 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "bracketSameLine": true, 3 | "bracketSpacing": true, 4 | "printWidth": 200, 5 | "semi": true, 6 | "singleQuote": true, 7 | "tabWidth": 4, 8 | "trailingComma": "none", 9 | "useTabs": false 10 | } 11 | -------------------------------------------------------------------------------- /views/layout/header.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Document 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /controllers/error.js: -------------------------------------------------------------------------------- 1 | const clientError = (req, res) => { 2 | res.status(404).send({ 3 | message: 'not a valid route' 4 | }); 5 | }; 6 | const serverError = (error, req, res, next) => { 7 | res.status(500).send({ 8 | message: error.message 9 | }); 10 | }; 11 | 12 | module.exports = { clientError, serverError }; 13 | -------------------------------------------------------------------------------- /config/db.js: -------------------------------------------------------------------------------- 1 | const mongoose = require("mongoose"); 2 | 3 | const { dev } = require("."); 4 | 5 | exports.connectDB = async () => { 6 | try { 7 | await mongoose.connect(dev.db.url); 8 | console.log("database is connected"); 9 | } catch (error) { 10 | console.log("database is not connected"); 11 | console.log(error.message); 12 | process.exit(1); 13 | } 14 | }; 15 | -------------------------------------------------------------------------------- /middlewares/fileUpload.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const multer = require('multer'); 3 | 4 | const storage = multer.diskStorage({ 5 | destination: function (req, file, cb) { 6 | cb(null, path.join(__dirname, '../public/images/')); 7 | }, 8 | filename: function (req, file, cb) { 9 | cb(null, Date.now() + '-' + file.originalname); 10 | } 11 | }); 12 | 13 | exports.upload = multer({ storage: storage }).single('image'); 14 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "node": true, 4 | "commonjs": true, 5 | "es2021": true 6 | }, 7 | "extends": "eslint:recommended", 8 | "overrides": [], 9 | "parserOptions": { 10 | "ecmaVersion": "latest" 11 | }, 12 | "rules": { 13 | "no-var": "error", 14 | "camelcase": "error", 15 | "no-empty": "error", 16 | "default-case": "error", 17 | "eqeqeq": "error", 18 | "max-lines": ["error", 150], 19 | "max-depth": ["error", 3] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /models/test.js: -------------------------------------------------------------------------------- 1 | const { Schema, model } = require('mongoose'); 2 | 3 | const testSchema = new Schema({ 4 | email: { 5 | type: String, 6 | required: [true, 'email is required'], 7 | trim: true, 8 | lowercase: true 9 | }, 10 | password: { 11 | type: String, 12 | required: [true, 'password is required'], 13 | minlength: [3, 'password must have atleast 3 characters'] 14 | }, 15 | createdAt: { 16 | type: Date, 17 | default: Date.now 18 | } 19 | }); 20 | 21 | exports.Test = model('Tests', testSchema); 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "morgan-middleware", 3 | "version": "1.0.0", 4 | "description": "a template for node, express, monggose", 5 | "main": "index.js", 6 | "scripts": { 7 | "start": "nodemon index.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "ISC", 12 | "dependencies": { 13 | "cors": "^2.8.5", 14 | "dotenv": "^16.0.3", 15 | "ejs": "^3.1.8", 16 | "express": "^4.18.2", 17 | "mongoose": "^6.6.5", 18 | "multer": "^1.4.5-lts.1", 19 | "swagger-jsdoc": "^6.2.5", 20 | "swagger-ui-express": "^4.5.0", 21 | "uuid": "^9.0.0" 22 | }, 23 | "devDependencies": { 24 | "chalk": "^4.1.2", 25 | "eslint": "^8.25.0", 26 | "eslint-config-airbnb-base": "^15.0.0", 27 | "eslint-plugin-import": "^2.26.0", 28 | "morgan": "^1.10.0", 29 | "nodemon": "^2.0.20" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const express = require('express'); 2 | const cors = require('cors'); 3 | const morgan = require('morgan'); 4 | const chalk = require('chalk'); 5 | const swaggerUi = require('swagger-ui-express'); 6 | const swaggerJsdoc = require('swagger-jsdoc'); 7 | 8 | const { connectDB } = require('./config/db'); 9 | const { clientError, serverError } = require('./controllers/error'); 10 | 11 | const app = express(); 12 | 13 | const port = process.env.PORT || 3000; 14 | 15 | app.listen(port, async () => { 16 | console.log(chalk.blue(`server is running at http://localhost:${port}`)); 17 | await connectDB(); 18 | }); 19 | 20 | // swagger setup starts 21 | const options = { 22 | definition: { 23 | openapi: '3.0.0', 24 | info: { 25 | title: 'Test API', 26 | version: '1.0.0', 27 | description: 'A REST Test API' 28 | }, 29 | servers: [ 30 | { 31 | url: `http://localhost:${port}` 32 | } 33 | ] 34 | }, 35 | apis: ['./controllers/*.js'] 36 | }; 37 | const openapiSpecification = swaggerJsdoc(options); 38 | app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(openapiSpecification)); 39 | // swagger setup ends 40 | 41 | // setting middlewares 42 | app.use(cors()); 43 | app.use(morgan('dev')); 44 | app.set('view engine', 'ejs'); 45 | app.use(express.json()); 46 | app.use(express.urlencoded({ extended: true })); 47 | 48 | app.get('/', (req, res) => { 49 | res.status(200).render('index'); 50 | }); 51 | 52 | app.use(clientError); 53 | app.use(serverError); 54 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | lerna-debug.log* 8 | .pnpm-debug.log* 9 | 10 | # Diagnostic reports (https://nodejs.org/api/report.html) 11 | report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json 12 | 13 | # Runtime data 14 | pids 15 | *.pid 16 | *.seed 17 | *.pid.lock 18 | 19 | # Directory for instrumented libs generated by jscoverage/JSCover 20 | lib-cov 21 | 22 | # Coverage directory used by tools like istanbul 23 | coverage 24 | *.lcov 25 | 26 | # nyc test coverage 27 | .nyc_output 28 | 29 | # Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) 30 | .grunt 31 | 32 | # Bower dependency directory (https://bower.io/) 33 | bower_components 34 | 35 | # node-waf configuration 36 | .lock-wscript 37 | 38 | # Compiled binary addons (https://nodejs.org/api/addons.html) 39 | build/Release 40 | 41 | # Dependency directories 42 | node_modules/ 43 | jspm_packages/ 44 | 45 | # Snowpack dependency directory (https://snowpack.dev/) 46 | web_modules/ 47 | 48 | # TypeScript cache 49 | *.tsbuildinfo 50 | 51 | # Optional npm cache directory 52 | .npm 53 | 54 | # Optional eslint cache 55 | .eslintcache 56 | 57 | # Optional stylelint cache 58 | .stylelintcache 59 | 60 | # Microbundle cache 61 | .rpt2_cache/ 62 | .rts2_cache_cjs/ 63 | .rts2_cache_es/ 64 | .rts2_cache_umd/ 65 | 66 | # Optional REPL history 67 | .node_repl_history 68 | 69 | # Output of 'npm pack' 70 | *.tgz 71 | 72 | # Yarn Integrity file 73 | .yarn-integrity 74 | 75 | # dotenv environment variable files 76 | .env 77 | .env.development.local 78 | .env.test.local 79 | .env.production.local 80 | .env.local 81 | 82 | # parcel-bundler cache (https://parceljs.org/) 83 | .cache 84 | .parcel-cache 85 | 86 | # Next.js build output 87 | .next 88 | out 89 | 90 | # Nuxt.js build / generate output 91 | .nuxt 92 | dist 93 | 94 | # Gatsby files 95 | .cache/ 96 | # Comment in the public line in if your project uses Gatsby and not Next.js 97 | # https://nextjs.org/blog/next-9-1#public-directory-support 98 | # public 99 | 100 | # vuepress build output 101 | .vuepress/dist 102 | 103 | # vuepress v2.x temp and cache directory 104 | .temp 105 | .cache 106 | 107 | # Docusaurus cache and generated files 108 | .docusaurus 109 | 110 | # Serverless directories 111 | .serverless/ 112 | 113 | # FuseBox cache 114 | .fusebox/ 115 | 116 | # DynamoDB Local files 117 | .dynamodb/ 118 | 119 | # TernJS port file 120 | .tern-port 121 | 122 | # Stores VSCode versions used for testing VSCode extensions 123 | .vscode-test 124 | 125 | # yarn v2 126 | .yarn/cache 127 | .yarn/unplugged 128 | .yarn/build-state.yml 129 | .yarn/install-state.gz 130 | .pnp.* -------------------------------------------------------------------------------- /controllers/swaggerTest.js: -------------------------------------------------------------------------------- 1 | /** 2 | *@swagger 3 | *components: 4 | * schemas: 5 | * Product: 6 | * type: object 7 | * required: 8 | * - title 9 | * - price 10 | * - rating 11 | * properties: 12 | * id: 13 | * type: string 14 | * description: auto generated id of the product 15 | * title: 16 | * type: string 17 | * description: title of the product 18 | * price: 19 | * type: number 20 | * description: price of the product 21 | * rating: 22 | * type: number 23 | * description: rating of the product 24 | * example: 25 | * id: ahiahuhauhuahuahuha 26 | * title: iphone14 27 | * price: 1450.55 28 | * rating: 4.5 29 | */ 30 | 31 | // grouping requests into tags 32 | /** 33 | * @swagger 34 | * tags: 35 | * name: Products 36 | * description: E-Commerce app 37 | */ 38 | 39 | /** 40 | * @swagger 41 | * /products: 42 | * get: 43 | * summary: Returns all the products 44 | * tags: [Products] 45 | * responses: 46 | * 200: 47 | * description: all the products 48 | * content: 49 | * application/json: 50 | * schema: 51 | * type: array 52 | * items: 53 | * $ref: '#/components/schemas/Product' 54 | */ 55 | 56 | /** 57 | * @swagger 58 | * /products/{id}: 59 | * get: 60 | * summary: get the product with id 61 | * tags: [Products] 62 | * parameters: 63 | * - in : path 64 | * name : id 65 | * schema: 66 | * type: string 67 | * required: true 68 | * description: product id 69 | * responses: 70 | * 200: 71 | * description: the product with id 72 | * content: 73 | * application/json: 74 | * schema: 75 | * $ref: '#/components/schemas/Product' 76 | * 404: 77 | * description: the product with id was not found 78 | */ 79 | 80 | /** 81 | * @swagger 82 | * /products: 83 | * post: 84 | * summary: create a new product 85 | * tags: [Products] 86 | * requestBody: 87 | * required: true 88 | * content: 89 | * application/json: 90 | * schema: 91 | * $ref: '#/components/schemas/Product' 92 | * responses: 93 | * 201: 94 | * description: the product was created 95 | * content: 96 | * application/json: 97 | * schema: 98 | * $ref: '#/components/schemas/Product' 99 | * 404: 100 | * description: the product with id was not found 101 | * 500: 102 | * description: server error 103 | */ 104 | 105 | /** 106 | * @swagger 107 | * /products/{id}: 108 | * put: 109 | * summary: update the product with id 110 | * tags: [Products] 111 | * parameters: 112 | * - in : path 113 | * name : id 114 | * schema: 115 | * type: string 116 | * required: true 117 | * description: product id 118 | * requestBody: 119 | * required: true 120 | * content: 121 | * application/json: 122 | * schema: 123 | * $ref: '#/components/schemas/Product' 124 | * responses: 125 | * 200: 126 | * description: the product was updated 127 | * 404: 128 | * description: the product with id was not found 129 | * 500: 130 | * description: server error 131 | */ 132 | 133 | /** 134 | * @swagger 135 | * /products/{id}: 136 | * delete: 137 | * summary: delete the product with id 138 | * tags: [Products] 139 | * parameters: 140 | * - in : path 141 | * name : id 142 | * schema: 143 | * type: string 144 | * required: true 145 | * description: product id 146 | * responses: 147 | * 200: 148 | * description: the product was deleted 149 | * 404: 150 | * description: the product with id was not found 151 | */ 152 | --------------------------------------------------------------------------------