-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from officialabdulrehman/rest-api
Rest api
- Loading branch information
Showing
11 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
MONGODB_LOCAL_URI = mongodb://localhost:27017/boilerplate | ||
MONGODB_URI = "your production mongo url" | ||
|
||
NODE_ENV = "not production" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
This project is only a sample to look and recreate your own rest-api with concepts from this project. | ||
It is not the super simple version, but it's not the most complex either. | ||
It has clean structure for better understanding. | ||
|
||
Starting point for this project is server.js which imports app.js containing all the logic | ||
|
||
follow the following steps to create your own services | ||
|
||
1 create model | ||
2 create service | ||
3 create router | ||
4 import and use the router in app.js | ||
|
||
NOTE: This project can be massively improved. I have kept it simple for the ease of understanding for beginners. | ||
|
||
Full version of this boiler-plate: https://github.com/officialabdulrehman/node-express-restapi-boilerplate | ||
|
||
Auther: https://github.com/officialabdulrehman | ||
|
||
Happy Coding!!! |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import express from "express"; // import express | ||
|
||
import { DBConnect } from "./config/database/connection"; // import database connection function | ||
|
||
import { MONGODB_URI, PORT } from "./utils/secrets"; // import secrets | ||
import { defaultErrorHandler, cors } from "./utils/apiHelpers"; // import helper functions | ||
|
||
import { userRouter } from "./routers/user/user"; // import router | ||
|
||
export const app = express(); // create app/server, store it in app - export | ||
export default app; // default export | ||
|
||
DBConnect(MONGODB_URI); // connect database ( call DBConnect and pass mongo uri) | ||
|
||
app.use(cors); // enable cors | ||
|
||
app.set("port", PORT || 3000); // set server port | ||
app.use(express.json()); // parse json | ||
|
||
app.use("/api/v1/user", userRouter); // initialize router here | ||
|
||
app.use(defaultErrorHandler); // handle errors at one place |
26 changes: 26 additions & 0 deletions
26
Backend Development/rest-api-demo/config/database/connection.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import mongoose from "mongoose"; | ||
import bluebird from "bluebird"; | ||
|
||
export const DBConnect = async (mongoUrl) => { | ||
mongoose.Promise = bluebird; | ||
|
||
const connectionP = new Promise((res, rej) => { | ||
mongoose | ||
.connect(mongoUrl) | ||
.then((ins) => { | ||
console.log("Mongo connected!!!"); | ||
console.log( | ||
`Using mongo host '${mongoose.connection.host}' and port '${mongoose.connection.port}'` | ||
); | ||
return res(ins); | ||
}) | ||
.catch((err) => { | ||
console.log( | ||
`MongoDB connection error. Please make sure MongoDB is running. ${err}` | ||
); | ||
return rej(err); | ||
}); | ||
}); | ||
|
||
return connectionP; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import mongoose from "mongoose"; | ||
|
||
const { Schema, model } = mongoose; | ||
|
||
const schemaFields = { | ||
email: { type: String, required: true, unique: true }, | ||
name: { type: String, required: false }, | ||
age: { type: Number, required: false }, | ||
}; | ||
|
||
const schema = new Schema(schemaFields, { timestamps: true }); | ||
|
||
export const UserModel = model("User", schema); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
{ | ||
"name": "server", | ||
"version": "1.0.0", | ||
"description": "rest-api-boilerplate-basic", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1", | ||
"start": "node index.js", | ||
"nodemon": "nodemon --experimental-modules --es-module-specifier-resolution=node index.js" | ||
}, | ||
"author": "NizTheDev", | ||
"license": "MIT", | ||
"devDependencies": { | ||
"nodemon": "^2.0.6" | ||
}, | ||
"dependencies": { | ||
"axios": "^0.21.1", | ||
"dotenv": "^8.2.0", | ||
"express": "^4.17.1", | ||
"express-validator": "^6.7.0", | ||
"mongoose": "^5.13.7", | ||
"validator": "^13.5.2" | ||
}, | ||
"type": "module" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
import { Router } from "express"; | ||
import userService from "../services/user"; | ||
import { response, restApiValidation } from "../utils/apiHelpers"; | ||
|
||
export const userRouter = Router(); | ||
export default userRouter; | ||
|
||
userRouter.get("/", [], async (req, res, next) => { | ||
restApiValidation(req, res, next); | ||
const page = parseInt(req.params.page) || 1; | ||
const perPage = parseInt(req.params.perPage) || 10; | ||
const result = await userService.list(page, perPage); | ||
response(res, result); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { app } from "./app"; // import app | ||
|
||
// run app by starting to listen | ||
const server = app.listen(app.get("port"), () => { | ||
console.log( | ||
`App is running at http://localhost:${app.get("port")} in ${app.get( | ||
"env" | ||
)} mode` | ||
); | ||
console.log(" Press CTRL-C to stop\n"); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import { UserModel } from "../models/user"; | ||
|
||
class UserService { | ||
transformUser(user) { | ||
return { | ||
email: user.email, | ||
name: user.name, | ||
age: user.age, | ||
}; | ||
} | ||
|
||
async list(page, perPage) { | ||
let skip = (page - 1) * perPage; | ||
skip = page > 1 ? skip - 1 : skip; | ||
const limit = page > 1 ? perPage + 2 : perPage + 1; | ||
const user = await UserModel.find({}).skip(skip).limit(limit).sort(sort); | ||
return this.transformUser(user); | ||
} | ||
} | ||
|
||
export const userService = new UserService(userDAO); | ||
export default userService; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
export const defaultErrorHandler = (err, req, res, next) => { | ||
const { code, message, data } = err; | ||
res.status(code || 500).json({ | ||
message: message || "Internal server error", | ||
result: {}, | ||
errors: data || [], | ||
}); | ||
}; | ||
|
||
export const cors = (req, res, next) => { | ||
res.setHeader("Access-Control-Allow-Origin", "*"); | ||
res.setHeader( | ||
"Access-Control-Allow-Methods", | ||
"GET, POST, PUT, PATCH, DELETE" | ||
); | ||
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization"); | ||
if (req.method === "OPTIONS") return res.sendStatus(200); | ||
next(); | ||
}; | ||
export default cors; | ||
|
||
export const restApiValidation = (req, res, next) => { | ||
const errors = validationResult(req); | ||
if (!errors.isEmpty()) { | ||
const error = new Error(`Bad Request`); | ||
error.data = errors.array().map((err) => { | ||
return { | ||
message: err.msg || "", | ||
param: err.param || "", | ||
location: err.location || "", | ||
value: err.value || "", | ||
}; | ||
}); | ||
error.code = 400; | ||
throw error; | ||
} | ||
return true; | ||
}; | ||
|
||
export const response = (res, result) => { | ||
const response = { | ||
message: "Success", | ||
result: result, | ||
errors: [], | ||
}; | ||
res.status(200).json(response); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import dotenv from "dotenv"; | ||
dotenv.config(); | ||
|
||
const ENVIRONMENT = process.env.NODE_ENV; | ||
const prod = ENVIRONMENT === "production"; | ||
export const MONGODB_URI = prod | ||
? process.env["MONGODB_URI"] | ||
: process.env["MONGODB_LOCAL_URI"]; | ||
|
||
export const PORT = process.env.PORT; | ||
|
||
if (!MONGODB_URI) { | ||
if (prod) { | ||
throw new Error( | ||
"No mongo connection string. Set MONGODB_URI environment variable." | ||
); | ||
} else { | ||
throw new Error( | ||
"No mongo connection string. Set MONGODB_URI_LOCAL environment variable." | ||
); | ||
} | ||
} |