Skip to content

MVP #73

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 11 commits into
base: main
Choose a base branch
from
Open

MVP #73

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
44 changes: 29 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,17 @@ In meeting the minimum viable product (MVP) specifications listed below, your pr

### Task 1: Project Set Up

- [ ] Fork and clone this repository. **If you are repeating this Course, delete your old fork from Github and re-fork and re-clone.**
- [ ] Create a new branch: `git checkout -b <firstName-lastName>`.
- [ ] Implement the project on your newly created branch, committing changes regularly.
- [ ] Push commits: `git push origin <firstName-lastName>`.
- [ ] **RUN** `npm install` to install your dependencies.
- [ x] Fork and clone this repository. **If you are repeating this Course, delete your old fork from Github and re-fork and re-clone.**
- [x ] Create a new branch: `git checkout -b <firstName-lastName>`.
- [ x] Implement the project on your newly created branch, committing changes regularly.
- [ x] Push commits: `git push origin <firstName-lastName>`.
- [ x] **RUN** `npm install` to install your dependencies.

### Task 2: CodeGrade Setup

- [ ] Follow [instructions](https://www.notion.so/lambdaschool/Submitting-an-assignment-via-Code-Grade-A-Step-by-Step-Walkthrough-07bd65f5f8364e709ecb5064735ce374) to set up Codegrade's Webhook and Deploy Key, making sure your deployment is set to your `<firstName-lastName>` branch.
- [ ] Push your first commit: `git commit --allow-empty -m "first commit" && git push`.
- [ ] Check to see that Codegrade has accepted your git submission.
- [ x] Follow [instructions](https://www.notion.so/lambdaschool/Submitting-an-assignment-via-Code-Grade-A-Step-by-Step-Walkthrough-07bd65f5f8364e709ecb5064735ce374) to set up Codegrade's Webhook and Deploy Key, making sure your deployment is set to your `<firstName-lastName>` branch.
- [ x] Push your first commit: `git commit --allow-empty -m "first commit" && git push`.
- [ x] Check to see that Codegrade has accepted your git submission.

### Task 3: Project Requirements (MVP)

Expand All @@ -38,27 +38,27 @@ Your finished project must include all of the following requirements:

A _"test"_ script already exists you can use to run tests against your code.

- [ ] Write an _npm script_ named _"start"_ that uses `node` to run the API server.
- [ ] Write an _npm script_ named _"server"_ that uses `nodemon`to run the API server.
- [ ] Install _nodemon_ as a development dependency only that would not be used in production.
- [ x] Write an _npm script_ named _"start"_ that uses `node` to run the API server.
- [ x] Write an _npm script_ named _"server"_ that uses `nodemon`to run the API server.
- [x ] Install _nodemon_ as a development dependency only that would not be used in production.

#### Build an API

- [ ] Inside `api/actions/actions-router.js` build endpoints for performing CRUD operations on _actions_:
- [x] Inside `api/actions/actions-router.js` build endpoints for performing CRUD operations on _actions_:
- `[GET] /api/actions` returns an array of actions (or an empty array) as the body of the _response_.
- `[GET] /api/actions/:id` returns an action with the given `id` as the body of the _response_.
- `[POST] /api/actions` returns the newly created action as the body of the _response_.
- `[PUT] /api/actions/:id` returns the updated action as the body of the _response_.
- `[DELETE] /api/actions/:id` returns no _response_ body.

- [ ] Inside `api/projects/projects-router.js` build endpoints for performing CRUD operations on _projects_:
- [x] Inside `api/projects/projects-router.js` build endpoints for performing CRUD operations on _projects_:
- `[GET] /api/projects` returns an array of projects (or an empty array) as the body of the response.
- `[GET] /api/projects/:id` returns a project with the given `id` as the body of the _response_.
- `[POST] /api/projects` returns the newly created project as the body of the _response_.
- `[PUT] /api/projects/:id` returns the updated project as the body of the _response_.
- `[DELETE] /api/projects/:id` returns no _response_ body.

- [ ] Inside `api/projects/projects-router.js` add an endpoint for retrieving the list of actions for a project:
- [x] Inside `api/projects/projects-router.js` add an endpoint for retrieving the list of actions for a project:
- `[GET] /api/projects/:id/actions` sends an array of actions (or an empty array) as the body of the response.

- Both Projects and Actions have an optional `completed` property (see Database Schemas below). In both cases it's a boolean stored in the database as a 1 or a 0. Make sure to transform the raw `completed` values obtained from the db to `true` or `false`, before sending them back to the client.
Expand Down Expand Up @@ -140,7 +140,21 @@ After finishing your required elements, you can push your work further. These go
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.
1. Understand and explain the use of Middleware.
-Node helps the front-end and the back-end communicate because they use the same language. Node helps coders write servers using JavaScript
2. Understand and explain the use of Middleware.
-Middleware is code that is excuted when an end point is called. However, middleware is called before the code is written within the endpoint. If there is repeated lines in our code, middleware can keep our clean and dry.

1. The basic principles of the REST architectural style.
RESTful api's are very browser friendly.
REST APIs have six constraints:
-client-server architecture.
-stateless architecture.
-cacheable:
-layered system:
--code on demand
uniform interfaces
HATEOAS (Hypermedia As The Engine Of Application State).
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, but it needs to exist inside an Express application.
1. Describe tooling used to manually test the correctness of an API.
Tools such as POSTMAN or Insomnia have interfaces with calls for APIs. Select the call you want and test it!
87 changes: 86 additions & 1 deletion api/actions/actions-router.js
Original file line number Diff line number Diff line change
@@ -1 +1,86 @@
// Write your "actions" router here!
const express= require('express');
const Actions = require ('./actions-model.js');
const router = express.Router();
const mw = require('../middleware/middleware.js')

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

router.get('/api/actions/:id', async (req, res) => {
const {id} = req.params;

try {
const action = await Actions.get(id);
if (!action) {
res.status(404).json({ message: "The action with the specified id does not exist" });
} else {
res.status(200).json(action);
}
} catch (err) {
res.status(500).json({ Error: {err} });
}
});


router.post('/api/actions', async (req, res) => {
const body = req.body;
if (!body.project_id || !body.description || !body.notes) {
res.status(400).json({ message: "please fill in all required fields" });
} else {
try {
const newAction = await Actions.insert(body);
res.status(201).json(newAction);
} catch (err) {
res.status(500).json({ Error: {err} });
}
}
});

router.delete('/api/actions/:id', async (req, res) => {
const {id} = req.params;

try {
const deletedAction = await Actions.remove(id);
if (!deletedAction) {
res.status(404).json({ message: "The action with the specified id does not exist" });
} else {
res.status(200).json(deletedAction);
}
} catch (err) {
res.status(500).json({ Error: {err} });
}
});

router.put('/api/actions/:id', async (req, res) => {
const {id} = req.params;
const body = req.body;

if (!body.description && !body.notes) {
res.status(400).json({ message: "please fill in all the required fields" });
} else {
try {
const updatedAction = await Actions.update(id, body);
if (!updatedAction) {
res.status(404).json({ message: "The action with the specified id does not exist"});
} else {
res.status(200).json(updatedAction);
}
} catch (err) {
res.status(500).json({ Error: {err} });
}
};
});


router.use((err,req,res,next) => {
res.status(500).json({
message:"something blew up",
error:err.message
})})
module.exports = router;
54 changes: 54 additions & 0 deletions api/middleware/middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
const Actions= require('../actions/actions-model.js');
const Projects = require('../projects/projects-model.js');

const checkProjectsId = async (req,res,next) =>{
const {id} = req.params
try{
const project = await Projects.get(id)
if(!project){
res.status(400).json({message:`No project with id: ${id}`})
}else{
req.project = project
next()
}
}
catch(err){
res.status(500).json(`Server error: ${err}`)
}
}

const checkProjectsValidation = (req,res,next) =>{
if (!req.body.description) {
res.status(400).json({ message: 'description required' })
} else {
next()
}
}
const checkActionsId = async (req,res,next) =>{
const {id} = req.params
try{
const action = await Actions.get(id)
if(!action){
res.status(400).json({message:`No project with id: ${id}`})
}else{
req.action = action
next()
}
}
catch(err){
res.status(500).json(`Server error: ${err}`)
}
}
const checkActionValidation = (req,res,next) =>{
if (!req.body.name || !req.body.description) {
res.status(400).json({ message: 'user requires both name and description' })
} else {
next()
}
}
module.exports={
checkProjectsId,
checkProjectsValidation,
checkActionsId,
checkActionValidation
}
109 changes: 108 additions & 1 deletion api/projects/projects-router.js
Original file line number Diff line number Diff line change
@@ -1 +1,108 @@
// Write your "projects" router here!
const express= require('express');
const Projects = require('./projects-model.js');
const Actions = require('../actions/actions-model.js')
const router = express.Router();
const mw = require('../middleware/middleware.js')




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

router.get('/api/projects/:id', async (req, res) => {
const {id} = req.params;

try {
const project = await Projects.get(id);
if (!project) {
res.status(404).json({ message: "The project with the specified id does not exist" });
} else {
res.status(200).json(project);
}
} catch (err) {
res.status(500).json({ Error: {err} });
}
});
router.post('/api/projects', async (req, res) => {
const body = req.body;

if (!body.name || !body.description) {
res.status(400).json({ message: "Please provide name and description" });
} else {
try {
const newProject = await Projects.insert(body);
res.status(201).json(newProject);
} catch (err) {
res.status(500).json({ Error: {err} });
}
}
});
router.delete('/api/projects/:id', async (req, res) => {
const {id} = req.params;

try {
const deletedProject = await Projects.remove(id);
if (!deletedProject) {
res.status(404).json({ message: "The project with the given id does not exist" });
} else {
res.status(200).json(deletedProject);
}
} catch (err) {
res.status(500).json({ Error: {err} });
}
});

router.put('/api/projects/:id', async (req, res) => {
const {id} = req.params;
const body = req.body;

if (!body.name && !body.description) {
res.status(400).json({ message: "Please fill out the required fields" });
} else {
try {
const updatedProject = await Projects.update(id, body);
res.status(200).json(updatedProject);
} catch (err) {
res.status(500).json({ Error: {err} });
}
}
});



router.post('/api/projects/:id/actions', (req,res,next) =>{
const actionInfo={...req.body, hub_id: req.params.id}

Actions.add(actionInfo)
.then(action =>{
res.status(210).json(message)
}).catch(err =>{
next(err)
})

})

router.get('/api/projects/:id/actions', async (req, res) => {
const {id} = req.params;

try {
const projectActions = await Projects.getProjectActions(id);
res.status(200).json(projectActions);
} catch (err) {
res.status(500).json({ Error: {err} });
}
});

router.use((err,req,res,next) => {
res.status(500).json({
message:"something blew up",
error:err.message
})})
module.exports = router;
22 changes: 20 additions & 2 deletions api/server.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,25 @@
const express = require('express');
const server = express();
const morgan = require('morgan')//server logger
const helmet =require('helmet')// helmet encrypts server
const actionsRouter =require('./actions/actions-router')
const projectsRouter = require('./projects/projects-router')

// Complete your server here!
// Do NOT `server.listen()` inside this file!

server.use(helmet());
server.use(morgan('dev'));
server.use(express.json())
server.use(actionsRouter)
server.use(projectsRouter)

server.get('*', (req, res) => {
res.status(200).json({ message: 'Hopes this works!' })
})
server.get('/', (req, res) => {

res.send(`
<h2>Kato API</h2>
<p>Welcome Kato API</p>
`);
});
module.exports = server;
18 changes: 5 additions & 13 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
/*
play this: https://www.youtube.com/watch?v=d-diB65scQU
const server = require('./api/server.js')

Sing along:

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

Go code!
*/
const PORT = 4000;
server.listen(PORT, () =>{
console.log(`\n *** listening on port ${PORT} ***\n`)
})
Loading