- Node: a runtime environment that allows Javascript to be run outside of the browser
- Express: a framework for Node for handling HTTP requests
- index.js - point of entry for the app, where the app is imported and the server is started.
- app.js - the express app is created and started here, the db cofig and middleware are also setup here.
- controllers - an object with various methods to handle endpointes are here.
- router.js - functions for dealing with enpoints are here, the controllers are used within the request methods.
- models - where the schema for the data is created and exported
- package.json - contains the packages and scripts, among other things, for the application.
- create an express application
$ npm install express mongoose body-parser mongo --save
- this is the file where our express application is configured
- set up the express application
- in
app.js
const express = require('express'); const app = express(); module.exports = app;
app
is an object that is able to take requests from the server and run code
- runs application on a server
- in
index.js
const app = require('./app'); app.listen(3050, () => { console.log('Running on port 3050'); })
at this point when you run node index.js the server should run and you should see the log in the console
- the functions that will run when a certain route is reached
- in
controllers/<controllerName>.js
module.exports = { greeting(req, res) { res.send({ hi: 'there!!' }); },
- exports functions that takes an arg of app and runs certain controller functions on the app depending on the endpoint hit
- follows this pattern:
app.<method>(<route>, controller funtion)
- in
router.js
const controller = require('../controllers/users_controller'); module.exports = (app) => { app.get('/api', controller.greeting); }
- wire up the routes to the app, the functions in router will use the application as the arg
- in
router.js
const router = require('./router'); routes(app);
at this point you should be able to go to the api endpoint and seee the greeting returned from the greeting controller
- set up the database connection
- in
app.js
const mongoose = require('mongoose'); mongoose.Promise = global.Promise; mongoose.connect('mongodb://localhost/users_practice'); mongoose.connection .once('open',() => { console.log('db open'); }) .on('error', () => (error) => console.warn('Warning', error))
*to make sure db was created via terminal: $ mongo somewhere.mongolayer.com:10011/my_database -u username -p password > show collections (your db should appear)
- the model determines how data can be stored organized and manipulated
- the
schema
describes the orgnazination of the data - in models/.js
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const UserSchema = new Schema({ name: String, password: String }); const User = mongoose.model('user', UserSchema); module.exports = User;
- install and use bodyParser to parse the body of requests
- in
app.js
const bodyParser = require('body-parser') app.use(bodyParser.json());
- in the controller file: import the model and create the function
- in
controllers/<controllerName>/js
const Recipe = require('../models/Recipe'); create(req, res) { const recipeProps = req.body; Recipe.create(recipeProps) .then(recipe => res.send(recipe)) },
- wire up the controller with the
post()
method - in
router.js
app.post('/api/new', controller.create)
*to test out
- use post man, create a body and use the post request method
- in terminal:
show dbs use show collections db..find(); (the data you have just created should be here)
- create a controller called index that uses the
find()
method (.find({})
finds all the data) - in
controllers/<controllerName>/js
index(req, res) { User.find({}) .then(users => res.send(users)) }
- wire up the controller in the router file with the
get()
method - in
router.js
app.get('/api', controller.index);
should be able to go to /api and see the data
- create the delete controller with the
delete()
method - in
controllers/<controllerName>/js
delete(req, res) { const id = req.params.id; Recipe.findByIdAndRemove({ _id: id }) .then(recipe => res.send(recipe)) }
- wire up the controller in the router file
- in
router.js
app.delete('/api/users/:id', UsersController.delete);
you should be able to go to api/users/<id#> and then when you do the get request it is no longer there
- create the controller with the
put()
method - in
controllers/<controllerName.js
edit(req, res) { const id = req.params.id; const recipeProps = req.body; Recipe.findOneAndUpdate({ _id: id }, recipeProps) .then(() => Recipe.findById({ _id: id})) .then(recipe => res.send(recipe)) }
- wire up the controller in the router file
- in
router.js
app.put('/api/:id', controller.edit)
*to try out:
- as a put request in postman - go to api/<id#>
- change the body to what you want to change
- when you send and do a get index request the updated data should show
- Currently, if an id for the delete and edit functions are not found it gets stuck. Error handling lets the user know there was an error instead of pausing the application
- Middleware will have access to the request and response object, the
next
function, and the error object- error object: will be defined if the previous middleware throws an error
- next: a function that when run, goes to the next middleware
/****/ routes(app); app.use((err, req, res, next) => { res.status(422).send({ error: err.message}); })
- use the
next()
function in the controllers, if theres an error thecatch
block will run withnext
, allowing the code to go to the middleware (app.use
)edit(req, res, next) { const userId = req.params.id; const userProps = req.body; User.findOneAndUpdate({ _id: userId }, userProps) .then(() => User.findById({ _id: userId })) .then(user => res.send(user)) .catch(next) }, delete(req, res, next) { const userId = req.params.id; User.findByIdAndRemove({ _id: userId }) .then(user => res.send(user)) catch(next); }
now if you go in postman and try to delete or edit an id that doesn't exist, an error message will be the response
- allows for cross origin resource sharing
const cors = require('cors') app.use(cors())