This is not a question related to a bug.I’ve just created a very tiny node.js/express API
for education purposes.
I’ve created a very little API
and what i would like is to have your point of view about the design and projet architecture and what you would recommand be as advice in term of what i can improve in this code.
As it’s open sources you’re also welcome for pull requests
.
Notice : I’ve not considered aspects like logging
,ORM's
or specific packages for validation
or these kind of things.
Here is the github repo where i explain cleary how to run the project in the local computer.
https://github.com/jochri3/tiny-express-api
My code organization is in a MVC pattern:
|controllers
-posts.js
|middlewares
-bodyValidation.js
-postExists.js
|models
-post.js
|startups
-db.js
-routes.js
app.js
router.js
Here is the codes content:
controllers/posts.js
const Post=require('../models/post');
const index=async(req,res)=>{
const posts=await Post.getAll();
res.send({data:posts})
}
// const show=(req,res)=>{
// }
const create=async({body},res)=>{
await Post.create(body);
res.status(201).send({message:'post created successfully'});
}
const update=async({body,params:{id}},res)=>{
await Post.update(id,body)
res.status(201).send({message:'posts updated successfully'});
}
const destroy=async({params:{id}},res)=>{
await Post.delete(id);
res.status(202).send({message:'post deleted successfully'})
}
module.exports={
index,
// show,
create,
update,
destroy
}
middlewares/bodyValidate
module.exports=async({body},res,next)=>{
const bodyValues=Object.values(body);
if(bodyValues.some(value=>!value)){
return res.status(422).send({message:'Veuillez remplir tous les champs correctement'})
}
next();
}
middlewares/postExists.js
const connection=require("../startups/db")
module.exports=async(req,res,next)=>{
const {params:{id}}=req;
if(!id){
return res.status(404).send({message:'not found'})
}
const post=await connection.select().from('posts').where('id',id);
if(!post.length){
return res.status(404).send({message:'not found'})
}
req.post=post;
next();
}
models/post.js
const connection=require("../startups/db");
class Post{
static getAll(){
return connection.select().from("posts");
}
static update(id,data){
return connection('posts').where('id',id).update(data);
}
// static getOne(id){
// }
static delete(id){
return connection('posts').where('id', id).del();
}
static create(data){
return connection('posts').insert(data);
}
}
module.exports=Post;
startups/db.js
const knex=require("knex");
module.exports=knex({
client: 'sqlite3',
connection: {
filename: "./db.sqlite"
}
})
startups/routes.js
const express=require('express');
const {postsRouter}=require('../router')
module.exports=(app)=>{
app.use(express.json())
app.use('/api/posts',postsRouter)
}
app.js
const express=require("express");
const connection=require("./startups/db");
const app=express();
require('./startups/routes')(app,connection)
require('express-async-errors');
const port=8000
app.listen(port,()=>{
console.info(`Server in listening on port ${port}`)
})
router.js
const express=require('express');
//custom middlewares
const idExists=require("./middlewares/postsExists");
const bodyValidates=require("./middlewares/bodyValidate");
const PostsController=require("./controllers/posts")
const postsRouter=express.Router();
postsRouter.get('/',PostsController.index);
postsRouter.get('/:id',(idExists),async(req,res)=>{
res.send({data:req.post(0)});
});
postsRouter.post('/',(bodyValidates),PostsController.create)
postsRouter.put('/:id',(idExists,bodyValidates),PostsController.update)
postsRouter.delete('/:id',(idExists),PostsController.destroy)
module.exports={
postsRouter
}
You can view the project in codesandbox : https://codesandbox.io/s/angry-montalcini-vsbfb