Skip to content

code review #125

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,33 @@ We have provided test data for all the resources.
Be prepared to demonstrate your understanding of this week's concepts by answering questions on the following topics. You might prepare by writing down your own answers before hand.

1. The core features of Node.js and Express and why they are useful.

We use Node to write server code. Specifically, web services that communicate with clients using the JavaScript Object Notation (JSON) format for data interchange.Node.js uses the same programming language (JavaScript) and paradigm for both client and server. Using the same language, we minimize context switching and share code between the client and the server. Meanwhile Express is a framework that sits on top of Node.js, making it wasier to create web applications and services. Express is Simple, Unopinionated, Compatible with connecting Middleware. All packaged into clean, intuitive, and easy-to-use API.

1. Understand and explain the use of Middleware.

Middleware are functions used in connecting a bunch of isolated systems to interact and perform certain tasks. Typically all middlewares in nodejs/expressjs have access to request, response and next objects.
To sum up, middleware functions can perform the following tasks :

- Execute any code.
- Make changes to any part of the code.
- Uses request/response objects to modify the request and response objects.
-Call the next middleware which helps in attaching any number of middleware functions to get executed in the queue.

1. The basic principles of the REST architectural style.

REST is a generally agreed-upon set of principles and constraints. They are recommendations, not a standard. When designing a RESTful Eeb API, keep the following principles in mind:

- Everything is a resource.
- Each resource is accessible via a unique URI.
- Resources can have multiple representations.
- Communication happens over a stateless protocol (HTTP).
- Resource management happens via HTTP methods.

1. Understand and explain the use of Express Routers.

An Express Router behaves like a mini Express application. It can have its own Routing and Middleware, bit it needs to exist inside an express application. Think of routers as a way of organizing Express application you write separate pieces that can later be composed together.

1. Describe tooling used to manually test the correctness of an API.

HTTPIE, POSTMAN, CURL are all used to manually test API endpoints.
43 changes: 42 additions & 1 deletion api/actions/actions-middlware.js
Original file line number Diff line number Diff line change
@@ -1 +1,42 @@
// add middlewares here related to actions
const Actions = require('./actions-model')
const { actSchema } = require("./../schemas")

function handleError(err, req, res, next) {
res.status(err.status || 500).json({
message: err.message,
productionMessage: "Sorry, there was a problem!",
})
}

async function checkActionId(req, res, next) {
try {
const action = await Actions.get(req.params.id)
if(!action) {
next({ status: 404, message: "id was not found"})
} else {
req.actionById = action
next()
}
} catch (err) {
next(err)
}
}

async function checkCompleted(req, res, next) {
try {
const validate = await actSchema.validate(req.body, {
strict: false,
stripUnknown: true,
})
req.body = validate
next()
} catch (err) {
next({ status: 400, message: err.message })
}
}

module.exports = {
handleError,
checkActionId,
checkCompleted,
}
54 changes: 53 additions & 1 deletion api/actions/actions-router.js
Original file line number Diff line number Diff line change
@@ -1 +1,53 @@
// Write your "actions" router here!
const express = require('express')
const Actions = require('./actions-model')
const {
handleError,
checkActionId,
checkCompleted
} = require('./actions-middlware')
const { actionIdChecker } = require('../projects/projects-middleware')
const router = express.Router()

router.get('/', async (req, res, next) => {
try {
const actions = await Actions.get()
res.status(200).json(actions)
} catch (err) {
next(err)
}
})

router.get('/:id', checkActionId, (req, res) => {
res.status(200).json(req.actionById)
})

router.post('/', checkCompleted, actionIdChecker, async (req, res, next) => {
try {
const newAction = await Actions.insert(req.body)
res.status(201).json(newAction)
} catch (err) {
next(err)
}
})

router.put("/:id", checkCompleted, checkActionId, async (req, res, next) => {
try {
const updatedAction = await Actions.update(req.params.id, req.body)
res.status(200).json(updatedAction)
} catch (err) {
next(err)
}
})

router.delete("/:id", checkActionId, async (req, res, next) => {
try {
await Actions.remove(req.params.id)
res.status(200).send("deleted actions")
} catch (err) {
next(err)
}
})

router.use(handleError)

module.exports = router
51 changes: 50 additions & 1 deletion api/projects/projects-middleware.js
Original file line number Diff line number Diff line change
@@ -1 +1,50 @@
// add middlewares here related to projects
const Projects = require('../projects/projects-model')
const { actionSchema } = require("./../schemas")

function logger(req, res, next) {
console.log(`[${new Date().toISOString()}] ${req.method} request to ${req.url}`)
next()
}

function handleError(err, req, res, next) {
res.status(err.status || 500).json({
message: err.message,
productionMessage: "Sorry, there was a problem!",
})
}

async function actionIdChecker(req, res, next) {
try{
const action = await Projects.get(req.params.id || req.body.project_id)
if(!action) {
next ({
status: 404,
message: "project not found",
})
} else {
next()
}
} catch (err){
next(err)
}
}

async function validateAction(req, res, next) {
try{
const validated = await actionSchema.validate(req.body, {
strict: false,
stripUnknown: true,
})
req.body = validated
next()
} catch (err) {
next({ status: 400, message: err.message })
}
}

module.exports = {
logger,
handleError,
actionIdChecker,
validateAction,
}
79 changes: 78 additions & 1 deletion api/projects/projects-router.js
Original file line number Diff line number Diff line change
@@ -1 +1,78 @@
// Write your "projects" router here!
const express = require('express')
const Projects = require('./projects-model')
const {
handleError,
actionIdChecker,
validateAction
} = require('./projects-middleware')
const router = express.Router()

router.get('/', async(req, res, next) => {
try {
const projects = await Projects.get()
res.status(200).json(projects)
}
catch (err) {
next(err)
}
})

router.get('/:id', async(req, res, next) => {
const { id } = req.params
try {
const project = await Projects.get(id)
if(!project) {
res.status(404).json({
message: "Project Not Found"
})
} else {
res.status(200).json(project)
}
} catch (err) {
next(err)
}
})

router.post('/', validateAction, async (req, res, next) => {
try{
const newProject = await Projects.insert(req.body)
res.status(201).json(newProject)
} catch (err) {
next(err)
}
})

router.put("/:id", validateAction, actionIdChecker, async (req, res, next) => {
if (req.body.completed === undefined) {
next({ status: 400, message: "missing required fields"})
} else {
try {
const updatedAction = await Projects.update(req.params.id, req.body)
res.status(200).json(updatedAction)
} catch (err) {
next(err)
}
}
})

router.delete("/:id", actionIdChecker, async (req, res, next) => {
try {
await Projects.remove(req.params.id)
res.status(200).send("Deleted Project")
} catch (err) {
next(err)
}
})

router.get('/:id/actions', actionIdChecker, async (req, res, next) => {
try {
const projects = await Projects.getProjectActions(req.params.id)
res.status(200).json(projects)
} catch (err) {
next(err)
}
})

router.use(handleError)

module.exports = router
35 changes: 35 additions & 0 deletions api/schemas/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const yup = require('yup')

const actionSchema = yup.object().shape({
name: yup
.string()
.trim()
.required('name is required'),
description : yup
.string()
.trim()
.required('description is required'),
completed: yup
.boolean()
})

const actSchema = yup.object().shape({
project_id: yup
.number()
.required(),
description: yup
.string()
.trim()
.max(100, 'cannot be longer than 100 chars')
.required('description is required'),
notes: yup
.string()
.trim()
.required('notes are required'),
completed: yup.boolean()
})

module.exports = {
actionSchema,
actSchema
}
21 changes: 17 additions & 4 deletions api/server.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,22 @@
const express = require('express');
const server = express();
const actionsRouter = require('./actions/actions-router')
const projectsRouter = require('./projects/projects-router')
const { logger, handleError } = require('./projects/projects-middleware')

// Configure your server here
// Build your actions router in /api/actions/actions-router.js
// Build your projects router in /api/projects/projects-router.js
// Do NOT `server.listen()` inside this file!
server.use(express.json())
server.use('/api/actions', actionsRouter)
server.use('/api/projects', logger, projectsRouter)



server.use('*', (req, res, next) => {
next({
status: 404,
message: `${req.method} ${req.originalUrl} not found!`
})
})

// server.use(handleError)

module.exports = server;
18 changes: 6 additions & 12 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
/*
play this: https://www.youtube.com/watch?v=d-diB65scQU
require('dotenv').config()

Sing along:
const server = require('./api/server')
const PORT = process.env.PORT || 5000

here's a little code I wrote, please read the README word for word, don't worry, you got this
in every task there may be trouble, but if you worry you make it double, don't worry, you got this
ain't got no sense of what is REST? just concentrate on learning Express, don't worry, you got this
your file is getting way too big, bring a Router and make it thin, don't worry, be crafty
there is no data on that route, just write some code, you'll sort it out… don't worry, just hack it…
I need this code, but don't know where, perhaps should make some middleware, don't worry, just hack it

Pull your server into this file and start it!
*/
server.listen(PORT, () => {
console.log(`\n ***listening on PORT ${PORT}***\n`)
})
Loading