Section 1
Intro to Express: CRUD, MVC, REST, INDUCES and JSX
Begin with the End In Mind
- Read URL parameters
- Common error: two responses
- Common error: Place routes in correct order
- Multiple Params
- Request Object
- URL Queries
- Describe REST and list the various routes
- Create an Index route
- Create a Show route
- Enhance the data in your data array
- Define MVC and explain why it matters
- Move our data into a separate file
- Move our presentation code into an JSX file
CRUD, MVC, REST, INDUCES and JSX: Remember where we are going
Explanation
CRUD, MVC, REST, INDUCES and JSX: Remember where we are going
What is CRUD?
CRUD stands for Create
, Read
, Update
and Delete
. Why and how is this important you ask? Well CRUD is in everything you interact with online on a daily basis. Browsing Instagram and looking at posts? Thats Read
. Are you posting something? Well that's Create
. Didn't like that picture you posted? Delete
to the rescue and finally, liking pictures of adorable animals? Hello Udate
!
So now that we have a reference point, how does that relate to code?
Below you'll find a table that relates normal HTTP
actions to our CRUD operators.
HTTP Action | CRUD Operator |
---|---|
GET | Read |
POST | Create |
PUT | Update |
DELETE | Delete |
Breaking It Down
Create
A Create or POST
creates a new entry in a database that either you or someone else created. When we perform a POST
request, we send some amount of information to our data source, usually data from a form; and we create a new entry in the data source.
Read
The Read
or GET
operation is something that you interact with every day. Whenever you pull information from an api, you are performing a GET
request. GET
requests only allow users to view or read from a data source. This can be something as simple as you checking your email in the morning. We perform a GET
request to a server and if everything goes OK we get some type of information or data back.
Update
Update or PUT
works very similar to a POST
request. We are still sending along some sort of data to our data source, but instead of creating a new entry, we are actually updating an existing entry. In order to this, we need to target that entry specifically, most of the times using an id
. This allows us to send some new information to to our existing piece of data and overwrite it's existing attributes.
Delete
Delete does just as the name implies, it DELETE
's something from our data source. We target the specific piece of information in the same way we did with our PUT
request. This sends a request to the server to DELETE
this item.
Demonstration
Describe REST and list the various routes
- REST stands for Representational state transfer
- It's just a set of principles that describe how networked resources are accessed and manipulated
- We have 7 RESTful routes that allow us basic operations for reading and manipulating a collection of data:
URL | HTTP Verb | Action | Used For |
---|---|---|---|
/photos/ | GET | index | Displaying a list of all photos |
/photos/new | GET | new | Display HTML form for creating a new photo |
/photos | POST | create | Create a new photo |
/photos/:id | GET | show | Display a specific photo |
/photos/:id/edit | GET | edit | Return an HTML form for editing a photo |
/photos/:id | PATCH/PUT | update | Update a specific photo |
/photos/:id | DELETE | destroy | Delete a specific photo |
What is Index and Show
Imitation
Create an Index route
Setup our app
Let's have a set of resources which is just a javascript array. To create an index route, we'd do the following:
const express = require('express');
const app = express();
const fruits = ['apple', 'banana', 'pear'];
app.get('/fruits', (req, res) => {
res.send(fruits);
});
app.listen(3000, () => {
console.log('listening');
});
Now go to http://localhost:3000/fruits/
If you haven't already Install JSON Formatter to make viewing JSON easier
- JSON stands for Javascript Object Notation
- It's just a way to represent data that looks like a Javascript object or array
- JSON Formatter extension just makes it easier to view JSON data.
Install it:
- Go to https://chrome.google.com/webstore/detail/json-formatter/bcjindcccaagfpapjjmafapmmgkkhgoa
- Click on "Add To Chrome"
Create a Show route
To create a show route, we'd do this:
const express = require('express');
const app = express();
const fruits = ['apple', 'banana', 'pear'];
app.get('/fruits/', (req, res) => {
res.send(fruits);
});
//add show route
app.get('/fruits/:indexOfFruitsArray', (req, res) => {
res.send(fruits[req.params.indexOfFruitsArray]);
});
app.listen(3000,() => {
console.log('listening');
});
Now go to http://localhost:3000/fruits/1
Enhance the data in your data array
- Right now are data array
fruits
is just an array of strings - We can store anything in the array, though.
- Let's enhance our data a bit:
const express = require('express');
const app = express();
const fruits = [
{
name:'apple',
color: 'red',
readyToEat: true
},
{
name:'pear',
color: 'green',
readyToEat: false
},
{
name:'banana',
color: 'yellow',
readyToEat: true
}
];
app.get('/fruits/', (req, res) => {
res.send(fruits);
});
app.get('/fruits/:indexOfFruitsArray', (req, res) => {
res.send(fruits[req.params.indexOfFruitsArray]);
});
app.listen(3000, () => {
console.log('listening');
});
Define MVC and explain why it matters
CRUD, MVC, REST, INDUCES and JSX: Remember where we are going
One of the core tenants of good programming is to compartmentalize your code
Already our code is getting a little messy, we have data, app instantiation (listening), and routes all in one file
One way to keep an app from getting messy is to separate it out into three sections
- Models
- data (javascript variables)
- Views
- how the data is displayed to the user (HTML)
- Controllers
- the glue that connects the models with the views with logic
This allows various developers to divide up a large code base
- minimizes likelihood of developers overwriting each others code
- allows developers to specialize
- one can focus just on getting good with dealing with data
- one can focus just on getting good with html
- one can focus just on getting good with connecting the two
Think of MVC as a restaurant
- Models are the cook
- prepares food/data
- Views are the customer
- consumes food/data
- Controllers are the waiter
- brings food from cook to customer
- has no idea how food/data is prepared
- has no idea how the food/data is consumed
Move our data into a folder called Models
- Create a directory called models inside our app directory
- Inside /models, create your data file (fruits.js)
-
Put your fruits variable in there
const fruits = [ { name:'apple', color: 'red', readyToEat: true }, { name:'pear', color: 'green', readyToEat: false }, { name:'banana', color: 'yellow', readyToEat: true } ];
-
We now require that file in the original server.js
const fruits = require('./models/fruits.js'); //NOTE: it must start with ./ if it's just a file, not an NPM package
-
But, we could have multiple variables in our /models/fruits.js file.
- How does javascript know which variable in /models/fruits.js to assign to the fruits const in server.js (the result of the
require()
statment)? - We must tell javascript which variable we want to be the result of the
require()
statement in server.js
- How does javascript know which variable in /models/fruits.js to assign to the fruits const in server.js (the result of the
//at the bottom of /models/fruits.js
module.exports = fruits;
❓ Essential Review Questions
- In your own words, describe MVC.
- What does the acronym INDUCES stand for
- What is and Index Route and How does it differ from a Show Route?
Move our presentation code into an JSX file
Templating with JSX and Component Driven Development
Explanation
CRUD, MVC, REST, INDUCES and JSX: Remember where we are going
What is JSX ?
A Syntax that allows us to write our HTML, CSS and Javascript in the same file so that we can more easily create user interfaces React is one of the most well known users of JSX. But other libraries like Lit-HTML, and KofuJS use it as well.
jsx-view-engine
This is an Express view engine which renders React components on a server. It uses react because it was made by facebook. It renders static markup and does not support mounting those views on the client.
This is intended to be used as a replacement for existing server-side view solutions, like jade, ejs (Like we have been using), or handlebars.
JSX USES
You can use JSX as a template language to tell your server how to dynamically change your HTML ( That's what we'll be doing for now)
You can also use JSX for very very sophisticated Dom Manipulation, and that's what we'll be doing in in 2 weeks after we have a good handle on servers.
Demonstration
A different way of Seperating Concerns ( Component Driven Development )
Lets Think of Games
- Job is to fight
- Job is to fish
- Job is to heal people
We could seperate 1 big group of fishers, 1 big group of fighters, 1 big group of healers Each group runs itself and are just dependent upon eachother to survive
OR
We could make a bunch of smaller self sufficient group with a few fishers, a few fighters, a few healers
Not saying either is better but each has it's advantages.
Now we want to move our View code (HTML) into a separate file just like we did with the data
-
Install the NPM package EXPRESS React Views, react, react-dom (This will let us make our pages appear in the dom)
- this is a templating library that allows us to mix data into our html
- the HTML will change based on the data!
npm install jsx-view-engine react react-dom --save
- Create a views directory inside our app directory
-
Inside /views, create a file called
Show.jsx
(capitalized)- this will be the html for our show route
-
Put some html into
Show.jsx
const React = require('react') class Show extends React.Component { render () { return ( <h1> Show Page </h1> ); } } module.exports = Show;
- Now we need to go to our
server.js
file and set up our view engine and this must be done above our routes
app.set('view engine', 'jsx');
app.engine('jsx', require('jsx-view-engine').createEngine());
-
Now, instead of
res.send('some text')
, we can callres.render('Show')
- express will know to look inside the /views directory
-
it will send the html in the Show file as a response
app.get('/fruits/:indexOfFruitsArray', function(req, res){ res.render('Show'); });
Now lets mix our data into our HTML
-
Our route is acting like the controller now. Let's gather the data and pass it to the view
app.get('/fruits/:indexOfFruitsArray', function(req, res){ res.render('Show', { //second param must be an object fruit: fruits[req.params.indexOfFruitsArray] //there will be a variable available inside the ejs file called fruit, its value is fruits[req.params.indexOfFruitsArray] }); });
-
Access the data in the view:
const React = require('react') class Show extends React.Component { render () { const fruit = this.props.fruit return ( <div> <h1> Show Page </h1> The {fruit.name} is {fruit.color} {fruit.readyToEat? 'Its is ready to eat' : 'It is not ready to eat... Cant touch this' } </div> ); } } module.exports = Show;
- Note that we place javascript inside of curly braces as soon as you put curly braces React knows you want to execute js
❓ Essential Review Questions
- Where do we get Fruit From?
- What two lines of code make our application able to use the JSX View Engine
Map A Developers best friend
- Lets update the Index route
-
Now, instead of
res.send('some text')
, we can callres.render('Show')
- express will know to look inside the /views directory
-
it will send the html in the Index file as a response
app.get('/fruits', function(req, res){ res.render('Index', { fruits: fruits }); });
- Lets write our Index.jsx
const React = require('react');
class Index extends React.Component {
render() {
const { fruits } = this.props;
return (
<div>
<h1>Fruits Index Page</h1>
<ul>
{fruits.map((fruit, i) => {
return (
<li>
The{' '}
<a href={`/fruits/${i}`}>
{fruit.name}
</a>{' '}
is {fruit.color} <br></br>
{fruit.readyToEat
? `It is ready to eat`
: `It is not ready to eat`}
<br />
</li>
);
})}
</ul>
</div>
);
}
}
module.exports = Index;
❓ Essential Review Questions
- What is JSX?
- What does Map Do.