Intro to REST , URL and Query Parameters
- Read URL parameters
- Common error: two responses
- Common error: Place routes in correct order
- Multiple Params
- Request Object
- URL Queries
- Extra: Environment Variables
Read URL parameters
Most of the time, we'll use segments in the path section of the URL to modify how our application works.
To do this, we'll use request parameters. To the user, it'll just look like an extension of the url path.
Let's think of Amazon again. With 300 million products and counting, hard coding a route for each product and keeping track of it all would be nightmarish.
We'll work with a simplified example. Imagine a store: The Botany Express
that sells a few plants. Rather than having a dedicated route for each plant, the plants are stored as data (in our case an array of strings). We can access the data by passing in the index as a part of the request URL.
To set URL parameters in your server.js
, just add a colon after the forward slash and then a variable name.
'Regular' URL:
/plants
URL parameter:
/:indexOfPlantsArray
The entire route:
app.get('/:indexOfPlantsArray', (req, res) => {
res.send(plants[req.params.indexOfPlantsArray]);
});
We can access the value of :indexOfPlantsArray
with req.params.indexOfPlantsArray
Let's code together to see this in action.
In classwork
:
mkdir express_plants
cd express_plants
touch server.js
npm init
npm i express
const express = require('express');
const app = express();
const port = 3000;
const plants = ['Monstera Deliciosa', 'Corpse Flower', 'Elephant-Foot Yam', "Witches' Butter",];
app.get('/:indexOfPlantsArray', (req, res) => {
res.send(plants[req.params.indexOfPlantsArray]);
});
app.listen(port,() => {
console.log('listening on port' , port);
});
Start up your server in terminal
Now visit http://localhost:3000/0 in your browser
Monstera Deliciosa
Now visit http://localhost:3000/3 in your browser
Witch's Butter
Note: http://localhost:3000
error cannot GET (we didn't write a route for this)
Let's breakdown the contents of our localhost URL:
http://localhost:3000/2
\___/ \_______/ \__/ \_/
protocol host port path*
Path can be a URL or a URL parameter: it will look the same in the browser. The difference will be in the server.
A Common Error
You can only have one response for every request. If you try to send multiple responses you'll get an error. Let's try it!
app.get('/oops/:indexOfPlantsArray', (req, res) => {
res.send(plants[req.params.indexOfPlantsArray]);
// error cannot send more than one response!
res.send('this is the index: ' + req.params.indexOfPlantsArray);
});
We can, however, have multiple statements if we use our if
statements or other program logic correctly:
app.get('/fixed/:indexOfPlantsArray', (req, res) => {
if (plants[req.params.index]) {
res.send(plants[req.params.indexOfPlantsArray]);
} else {
res.send('cannot find anything at this index: ' + req.params.indexOfPlantsArray);
}
});
Place routes in correct order
- Express starts at the top of your
server.js
file and attempts to match the url being used by the browser with routes in the order in which they're defined -
URL params (e.g. :foo, :example, :indexOfPlantsArray) can be anything, a number, or even a string
- Therefore if you have these routes in this order in your
server.js
: /:color
/plants
- And you want to get to
/plants
- you'll always hit the/:color
route because the URL parameter will accept any string, it doesn't know thatplants
is something specific/special - To fix this, we put the more specific routes first
/plants
/:color
Now, from top to bottom, the more specific route/plants
will be triggered when the URL hasplants
and if it doesn't matchplants
, it will go to the next route.
- Therefore if you have these routes in this order in your
Let's code an example of this together:
const express = require('express');
const app = express();
const port = 3000;
const plants = ['Monstera Deliciosa', 'Corpse Flower', 'Elephant-Foot Yam', "Witches' Butter",];
app.get('/:indexOfPlantsArray', (req, res) => { //:indexOfPlantsArray can be anything, even awesome
res.send(plants[req.params.indexOfPlantsArray]);
});
app.get('/awesome', (req, res) => { //this will never be reached
res.send(`
<h1>Plants are awesome!</h1>
<img src="https://static.boredpanda.com/blog/wp-content/uuuploads/plant-sculptures-mosaicultures-internationales-de-montreal/plant-sculptures-mosaicultures-internationales-de-montreal-14.jpg" >
`);
});
app.listen(port,() => {
console.log('listening on port' , port);
});
If this happens, reorder them so that more specific routes come before less specific routes (those with params in them)
const express = require('express');
const app = express();
const port = 3000;
const plants = ['Monstera Deliciosa', 'Corpse Flower', 'Elephant-Foot Yam', "Witches' Butter",];
app.get('/awesome', (req, res) => {
res.send(`
<h1>Plants are awesome!</h1>
<img src="https://static.boredpanda.com/blog/wp-content/uuuploads/plant-sculptures-mosaicultures-internationales-de-montreal/plant-sculptures-mosaicultures-internationales-de-montreal-14.jpg" >
`);
});
app.get('/:indexOfPlantsArray', (req, res) => {
res.send(plants[req.params.indexofPlantsArray]);
});
app.listen(port,() => {
console.log('listening on port' , port);
});
Multiple Params
We can store multiple params in the req.params
object:
🔵 Write in (5 min)
app.get('/hello/:firstname/:lastname', (req, res) => {
console.log(req.params);
res.send('hello ' + req.params.firstname + ' ' + req.params.lastname);
});
- In your browser, go to
localhost:3000/hello/bob/bobbybob
🔵 Check the req.params console.log in Terminal
- Try entering different firstnames and lastnames in your URL and check the results
req.query
A query is a key-value pair separated with an =
, and added to the URL with a ?
.
?someKey=someValue
localhost:3000/howdy/bob?title=duke
app.get('/howdy/:firstName', function(req, res) {
console.log(req.params);
console.log(req.query);
res.send('hello ' + req.query.title + ' ' + req.params.firstName);
});
You can add multiple queries
localhost:3000/howdy/bob?title=duke&year=2001
Spaces are represented with a %20
.