2022-08-04 14:00:04 +01:00
|
|
|
---
|
2022-08-28 10:37:22 +01:00
|
|
|
tags: [backend, node-js, REST, APIs]
|
2022-08-04 14:00:04 +01:00
|
|
|
---
|
|
|
|
|
2022-08-30 10:00:04 +01:00
|
|
|
# Creating a RESTful API: `POST` requests
|
2022-08-04 14:00:04 +01:00
|
|
|
|
2024-02-02 15:58:13 +00:00
|
|
|
To demonstrate the handling of POST requests, we will create a handler that add
|
|
|
|
a new element to the array of courses.
|
2022-08-04 14:00:04 +01:00
|
|
|
|
|
|
|
```js
|
2022-08-30 10:00:04 +01:00
|
|
|
router.post("/", (req, res) => {
|
2022-08-28 10:37:22 +01:00
|
|
|
const course = {
|
|
|
|
id: courses.length + 1,
|
|
|
|
name: req.body.name,
|
|
|
|
};
|
|
|
|
courses.push(course);
|
|
|
|
res.send(course);
|
|
|
|
});
|
2022-08-04 14:00:04 +01:00
|
|
|
```
|
|
|
|
|
2024-02-02 15:58:13 +00:00
|
|
|
Here we use the body that is sent from the client and isolate the field `name`.
|
|
|
|
This presupposes that the client is sending us data with the following shape as
|
|
|
|
the body:
|
2022-08-04 14:00:04 +01:00
|
|
|
|
|
|
|
```json
|
|
|
|
{
|
2022-08-28 10:37:22 +01:00
|
|
|
"name": "Biology and Life Sciences"
|
|
|
|
}
|
2022-08-04 14:00:04 +01:00
|
|
|
```
|
|
|
|
|
|
|
|
To execute the PUT request from the frontend:
|
|
|
|
|
|
|
|
```js
|
|
|
|
const addCourse = async (newCourse) => {
|
|
|
|
try {
|
2022-08-30 10:00:04 +01:00
|
|
|
const resp = await axios.post("http://localhost:3000/api/courses", {
|
2022-08-04 14:00:04 +01:00
|
|
|
name: newCourse,
|
|
|
|
});
|
|
|
|
console.log(resp.data);
|
|
|
|
} catch (err) {
|
|
|
|
console.error(err);
|
|
|
|
}
|
|
|
|
};
|
2022-08-30 10:00:04 +01:00
|
|
|
addCourse("Biology and Life Sciences");
|
2022-08-04 14:00:04 +01:00
|
|
|
```
|
|
|
|
|
2022-08-28 10:37:22 +01:00
|
|
|
Which returns:
|
2022-08-04 14:00:04 +01:00
|
|
|
|
|
|
|
```js
|
|
|
|
{ id: 4, name: 'Biology and Life Sciences' }
|
|
|
|
```
|
|
|
|
|
2024-02-02 15:58:13 +00:00
|
|
|
The `id` is added by the server, not the client. Having created the new value we
|
|
|
|
add it to our `courses` array. (In reality we would be creating a new entry in a
|
|
|
|
database.) Then we follow the convention of returning the new value back to the
|
|
|
|
client.
|
2022-08-04 14:30:04 +01:00
|
|
|
|
|
|
|
## Validation
|
|
|
|
|
2024-02-02 15:58:13 +00:00
|
|
|
We should accept alterations to the database that are not first validated. We
|
|
|
|
can use the
|
2024-02-17 11:57:44 +00:00
|
|
|
[Joi validator](Validation.md) to vet
|
2024-02-02 15:58:13 +00:00
|
|
|
the request:
|
2022-08-04 14:30:04 +01:00
|
|
|
|
|
|
|
```js
|
|
|
|
function validateCourse(course) {
|
|
|
|
const schema = Joi.object({
|
|
|
|
name: Joi.string().min(3).required(),
|
|
|
|
});
|
|
|
|
|
2022-08-30 10:00:04 +01:00
|
|
|
const { error } = schema.validate(course);
|
2022-08-04 14:30:04 +01:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
```
|
2022-08-28 10:37:22 +01:00
|
|
|
|
2022-08-04 14:30:04 +01:00
|
|
|
We can then add the validation as part of our general error handling:
|
|
|
|
|
|
|
|
```js
|
2022-08-30 10:00:04 +01:00
|
|
|
router.post("/", (req, res) => {
|
2022-08-28 10:37:22 +01:00
|
|
|
const course = {
|
|
|
|
id: courses.length + 1,
|
|
|
|
name: req.body.name,
|
|
|
|
};
|
2022-08-30 10:00:04 +01:00
|
|
|
const { error } = schema.validate(req.body);
|
|
|
|
if (error)
|
|
|
|
return error.details.map((joiErr) => res.status(400).send(joiErr.message));
|
2022-08-28 10:37:22 +01:00
|
|
|
|
2022-08-04 14:30:04 +01:00
|
|
|
courses.push(course);
|
2022-08-28 10:37:22 +01:00
|
|
|
res.send(course);
|
|
|
|
});
|
2022-08-04 14:30:04 +01:00
|
|
|
```
|