diff --git a/api/middleware/middleware.js b/api/middleware/middleware.js index 0cceb716a..81e13d0a3 100644 --- a/api/middleware/middleware.js +++ b/api/middleware/middleware.js @@ -1,17 +1,65 @@ +const User = require('../users/users-model') + function logger(req, res, next) { // DO YOUR MAGIC + const timeStamp = new Date().toLocaleString() + const method = req.method + const url = req.originalUrl + // console.log('logger middleware'); + console.log(`[${timeStamp}] ${method} to ${url}`); + next() } -function validateUserId(req, res, next) { +async function validateUserId(req, res, next) { // DO YOUR MAGIC + try{ + const user = await User.getById(req.params.id) + if(!user){ + res.status(404).json({ + message: 'user not found' + }) + }else{ + req.user = user + next() + } + }catch(err){ + res.status(500).json({ + message: 'Problem finding user' + }) + } + next() } function validateUser(req, res, next) { // DO YOUR MAGIC + const { name } = req.body + if(!name || !name.trim()){ + res.status(400).json({ + message: 'missing required name field' + }) + }else { + req.name = name.trim() + next() + } } function validatePost(req, res, next) { // DO YOUR MAGIC + const { text } = req.body + if(!text || text.trim()) { + res.status(400).json({ + message: 'missing required text field' + }) + }else { + req.name = text.trim() + next() + } } // do not forget to expose these functions to other modules +module.exports = { + logger, + validateUserId, + validateUser, + validatePost +} \ No newline at end of file diff --git a/api/server.js b/api/server.js index badc3026a..010d9eeae 100644 --- a/api/server.js +++ b/api/server.js @@ -1,9 +1,12 @@ const express = require('express'); +const userRouter = require('../api/users/users-router') +const { logger } = require('./middleware/middleware') const server = express(); - // remember express by default cannot parse JSON in request bodies - +server.use(express.json()) +server.use('/api/users', userRouter) +server.use(logger) // global middlewares and the user's router need to be connected here server.get('/', (req, res) => { diff --git a/api/users/users-router.js b/api/users/users-router.js index 9d8a0e278..d67328e13 100644 --- a/api/users/users-router.js +++ b/api/users/users-router.js @@ -1,44 +1,97 @@ const express = require('express'); // You will need `users-model.js` and `posts-model.js` both +const User = require('./users-model') +const Posts = require('../posts/posts-model') + // The middleware functions also need to be required +const { validateUserId, validateUser, validatePost } = require('../middleware/middleware') const router = express.Router(); -router.get('/', (req, res) => { +router.get('/', (req, res, next) => { // RETURN AN ARRAY WITH ALL THE USERS + User.get() + .then(users => { + res.json(users) + }) + .catch(next) }); -router.get('/:id', (req, res) => { +router.get('/:id', validateUserId, (req, res) => { // RETURN THE USER OBJECT // this needs a middleware to verify user id + res.json(req.user) }); -router.post('/', (req, res) => { +router.post('/', validateUser, (req, res, next) => { // RETURN THE NEWLY CREATED USER OBJECT // this needs a middleware to check that the request body is valid + User.insert({ name: req.name }) + .then(newUser => { + res.status(201).json(newUser) + }) + .catch(next) }); -router.put('/:id', (req, res) => { +router.put('/:id', validateUserId, validateUser, (req, res, next) => { // RETURN THE FRESHLY UPDATED USER OBJECT // this needs a middleware to verify user id // and another middleware to check that the request body is valid + User.update(req.params.id, { name: req.name }) + .then(() => { + return User.getById(req.params.id) + }) + .then(user => { + res.status(201).json(user) + }) + .catch(next) }); -router.delete('/:id', (req, res) => { +router.delete('/:id', validateUserId, async (req, res, next) => { // RETURN THE FRESHLY DELETED USER OBJECT // this needs a middleware to verify user id + try{ + await User.remove(req.params.id) + res.json(req.user) + }catch(err){ + next(err) + } }); -router.get('/:id/posts', (req, res) => { +router.get('/:id/posts', validateUserId, async (req, res, next) => { // RETURN THE ARRAY OF USER POSTS // this needs a middleware to verify user id -}); + try{ + const posts = await User.getUserPosts(req.params.id) + res.json(posts) + }catch(err){ + next(err) + } +}); -router.post('/:id/posts', (req, res) => { +router.post('/:id/posts', validateUserId, validatePost, async (req, res, next) => { // RETURN THE NEWLY CREATED USER POST // this needs a middleware to verify user id // and another middleware to check that the request body is valid + try{ + const newPost = await Post.insert({ + user_id: req.params.id, + text: req.text, + }) + res.status(201).json(newPost) + }catch (err){ + next(err) + } }); +router.use((err, req, res, next) => { + res.status(err.status || 500).json({ + customMessage: 'Error inside user router', + message: err.message, + stack: err.stack + }) +}) + // do not forget to export the router +module.exports = router \ No newline at end of file diff --git a/data/database.db3 b/data/database.db3 index 90697a674..be0d441d8 100644 Binary files a/data/database.db3 and b/data/database.db3 differ diff --git a/index.js b/index.js index 602039f1b..06c1ec639 100644 --- a/index.js +++ b/index.js @@ -1 +1,10 @@ // require your server and launch it +const server = require('./api/server') + +require('colors') + +const port = 9000 + +server.listen(port, () => { + console.log(`Server listening on port ${port}`); +}) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a073034f1..208c2d856 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "packages": { "": { - "name": "node-api3-project", "version": "1.0.0", "dependencies": { + "colors": "^1.4.0", "express": "^4.17.1", "knex": "^0.95.14", "sqlite3": "^5.0.2" @@ -1995,6 +1995,14 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" }, + "node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "engines": { + "node": ">=0.1.90" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -8782,6 +8790,11 @@ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==" }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", diff --git a/package.json b/package.json index 8f31b3fe7..bb3f148a1 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "url": "git+https://github.com/BloomInstituteOfTechnology/node-api3-project.git" }, "dependencies": { + "colors": "^1.4.0", "express": "^4.17.1", "knex": "^0.95.14", "sqlite3": "^5.0.2"