All examples are using ReactJS as the frontend library and Axios as the request handler.
For now, think of servers as the middle man between the client and the database.
The only thing the client really needs is information from the database but it's not safe for clients to directly connect to databases and query information for themselves.
That's where servers come in. Servers can validate clients and serve up information from the database depending on their requests.
METAPHOR TIME
Think of a restuarant:
Clients are the customers.
Servers are the waiters.
Chefs are the databases.
A customer reads the menu (our API) and orders something (makes a request for data).
The waiter receives the request, makes sense of what they're asking, and asks the chef to cook up the menu item.
The chef (database management system) does some work (queries the database), and let's the waiter know that the food is ready.
Then, the waiter comes by, picks up the food, and serves it to the client.
const express = require('express');
const path = require('path');
const bodyParser = require('body-parser');
const router = require(<PATH_TO_ROUTER>);
const app = express();
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
app.use('/api', router);
app.use(express.static(path.resolve(__dirname, <PATH_TO_STATIC_ASSETS>)));
module.exports = app;
const http = require('http');
const app = require(<PATH_TO_APP>);
const server = http.createServer(app);
const PORT = 3000;
server.listen(PORT, (err) => {
if (err) {
console.log('err starting server = ', err);
}
console.log('successfully started server on PORT ', PORT);
});
Associated with POST
, PUT
, && PATH
requests
If you want to write to the database, then use one of the aforementioned methods.
HOW IT LOOKS
Frontend
import React, { Component } from 'react';
import axios from 'axios';
class Example extends Component {
constructor() {
super();
this.state = {
username: '',
password: '',
users: []
}
};
componentDidMount() {
const { username, password, users } = this.state;
axios.post('/api/users', {
username,
password
})
.then(({ data }) => {
this.setState({
users: [...users, data]
})
})
.catch(err => {
// error handling
})
}
}
Backend (simplified)
app.post('/api/users', (req, res) => {
db.create(req.body)
.then(d => res.status(201).send(d))
.catch(err => res.status(500).send(err));
});
We use these for GET
&& DELETE
Frontend
import React, { Component } from 'react';
import axios from 'axios';
class Example extends Component {
constructor() {
super();
this.state = {
username: '',
users: []
}
};
componentDidMount() {
const { username, users } = this.state;
axios.get(`/api/users/${username}`)
.then(({ data }) => {
this.setState({
users: [...users, data]
})
})
.catch(err => {
// error handling
})
}
}
Backend (simplified)
app.get('/api/users/:username', (req, res) => {
const { username } = req.params;
db.find(username)
.then(d => res.status(200).send(d))
.catch(err => res.status(500).send(err));
});
We define properties of the params
object inside the endpoint itself. Anything following :
will become a property of the params
object. In this case, it's username
.
We then give those properties values in the request by replacing :property
. In this case, it's username
from the state object inside our React component.
Another way to provide information to our server. We can go into best practices for this later on but a brief intro:
Frontend
import React, { Component } from 'react';
import axios from 'axios';
class Example extends Component {
constructor() {
super();
this.state = {
username: '',
password: '',
users: []
}
};
componentDidMount() {
const { username, users } = this.state;
axios.get(`/api/users?username=${username}&password=${password}`)
.then(({ data }) => {
this.setState({
users: [...users, data]
})
})
.catch(err => {
// error handling
})
}
}
Backend (simplified)
app.get('/api/users', (req, res) => {
const { username, password } = req.query;
db.find(username)
.then(d => res.status(200).send(d))
.catch(err => res.status(500).send(err));
})
As you can see, we don't define properties of the query
object anywhere like we did with params
. Also, there's not any visible indication in the route itself that this will receive a query
object either. query
is just a property of the request
object as is params
.
Here's a portion of the request
object from the above request:
params: {},
query: { username: 'hello', password: 'hi' },
So, there ya have it. body
, params
, && query
are just properties of the request object we can use to send information from the client to the server. It's just standard convention to use one of these properties for a certain request.