Objectives |
---|
Explain parsing URL params and using query string params |
Apply routing knowledge to build an Express application with dynamic routes |
Explain the usefulness of middleware (e.g., body-parser ) |
- HTTP
- Resource path
- Query string
- HTTP verb
- Status code
- Middleware
- Intro
- Routing
- HTTP GET
- Request Params
- Query Params
- Middleware
- Exercises
Core Concepts and Brainstorming
- Server-side JS
- Instead of DOM manipulation, we are interacting with the request / response cycle
- (B.Y.O.A.) Build your own API
- What kind of data do you want to work with?
Let's start with a simple Express application.
-
Inside your fork of this repo, make a directory and
index.js
mkdir quick_example cd quick_example/ touch index.js
-
Then create a
package.json
, use the first line below ornpm init
.echo {} > package.json #puts an empty object into a new `package.json` npm install --save express npm install --save ejs # if you want to use the templating subl .
The folder structure will be as follows:
/quick_example
/node_modules
/express
...
index.js
package.json
Now we need write some code for our simple application.
index.js
// requirements
var express = require('express'),
app = express();
// a "GET" request to "/" will run the function below
app.get("/", function (req, res) {
// send back the response: 'Hello World'
res.send("Hello World");
});
// start the server
app.listen(3000, function () {
console.log("Go to localhost:3000/");
});
Now you can start the server:
node index.js
Building an application will require us to have a firm grasp of something we call routing. Each route is a combination of a Request Type and Path.
Request Type | Request Path | Response |
---|---|---|
GET |
/ |
Hello World |
GET |
/burgers |
Hamburger , Cheese Burger , Dble Cheese Burger |
GET |
/tacos |
Soft Taco , Crunchy Taco , Super Taco |
Let's build these into our application:
index.js
var express = require('express'),
app = express();
var burgers = [
"Hamburger",
"Cheese Burger",
"Dble Cheese Burger"
];
var tacos = [
"Soft Taco",
"Crunchy Taco",
"Super Taco"
];
app.get("/", function (req, res) {
res.send("Hello World");
});
app.get("/burgers", function (req, res) {
//send all the burgers
res.send(burgers.join(", "));
});
app.get("/tacos", function (req, res) {
//send all the tacos
res.send(tacos.join(", "));
});
app.listen(3000, function () {
console.log("Go to localhost:3000/");
});
What if we want to create an app that can dynamically say hello to anyone?
- Using url parameters add a dynamic route to the application, indicated by
:
and the variable name you want to use, we'll use:name
for the example below.
// another example of some simple middleware
// call this function on every route with the param of 'name'
app.param('name', function(request, response, next) {
// get name from params
var name = request.params.name;
// capitalize the name
var capitalizedName = name[0].toUpperCase() + name.slice(1).toLowerCase();
// set the value of the name to the capitalized version
request.params.name = capitalizedName;
// pass control to the next middleware function
next();
})
app.get("/greet/:name", function (req, res) {
res.send( "Hello, " + req.params.name );
});
Here we are seeing the first introduction to parameters that the application can identify. In the following route :name
is consider a route parameter. We can access it using req.params.name
.
Request Type | Request Path | Response |
---|---|---|
GET |
/greet/:name |
Hello, :name |
Generally, you don't want to cram everything into a route. Just imagine when there are multiple parameters in route. Or maybe we don't care about getting the order of the parameters correct. Luckily, there are query parameters you can include with each request.
Let's see query params in action. Go to https://google.com/search?q=kittens&tbm=isch
?
denotes the beginning of the query parameters=
indicates an assignment; anything to the left is the key, while the right represents the value&
allows for the input of multiple parameters, separating each
Let's add our first route to practice query params.
app.get("/thank", function (req, res) {
var name = req.query.name;
res.send("Thank you, " + name);
});
Reset your server and go to localhost:3000/thank?name=jane. Note how we can now define parameters in the url after a ?
.
What is middleware? In terms of Express, middleware is a function with access to the request object (req), the response object (res), and the next middleware in the application’s request-response cycle, commonly denoted by a variable named next.
Middleware can:
- Execute any code.
- Make changes to the request and the response objects.
- End the request-response cycle.
- Call the next middleware in the stack.
You can create your own middleware, or use third-party modules. That's right, there are tons of useful middlewares that are already out there which you can use to handle common challenges like authentication, validations, and parsing.
The body-parser
module is an example of some middleware that makes Express awesome. You can use it to parse out params from the POST'd form. This provides a different way to collect data instead of relying on URL or query params.
server.js
var express = require('express');
var app = express();
var ejs = require('ejs');
var bodyParser = require('body-parser');
// bodyParser.urlencoded() returns a function that will be called later in the app.post() route
var parseUrlencoded = bodyParser.urlencoded({extended: false});
// store for cities in memory (as long as server is running)
var cities = [];
app.get('/cities', function(req, res) {
res.render('cities', {cities: cities});
})
// passing multiple middleware functions to this route; they are executed sequentially.
app.post('/cities', parseUrlencoded, function (request, response) {
var city;
var name = request.body.name;
var description = request.body.description;
city = { name: name, description: description}
cities.push(city);
// passing local variables to be used in EJS template
response.render('cities', { cities: cities});
});
cities.ejs
<h1>Cities</h1>
<ul>
<% for(var i = 0; i< cities.length; i++) {%>
<li><%= cities[i].name %> <%= cities[i].description %></li>
<% } %>
</ul>
<form action="/cities" method="POST">
<input type="text" name="name">
<input type="text" name="description">
<input type="submit" value="submit">
</form>
We learned about
- Routing to different resources, i.e.
/burgers
and/tacos
- Using dynamic parameters, i.e.
/burgers/:index
and/tacos/:index
to request specific data - Using query parameters for dynamic requests to serve up dynamic responses
- What middleware is and why it is helpful
This will be essential knowledge for building and interacting with applications that contain multiple resources, such as users, posts, comments, etc.
Now let's jump into a routing challenge. Follow this link and complete them in your fork of this repo, then push all your changes up to your remote repo.
All content is licensed under a CCBYNCSA 4.0 license. All software code is licensed under GNU GPLv3. For commercial use or alternative licensing, please contact legal@ga.co.