2022-07-12 18:00:04 +01:00
|
|
|
---
|
2024-06-15 11:00:03 +01:00
|
|
|
tags:
|
|
|
|
- node-js
|
|
|
|
- REST
|
|
|
|
- APIs
|
2022-07-12 18:00:04 +01:00
|
|
|
---
|
|
|
|
|
2022-08-30 10:00:04 +01:00
|
|
|
# Creating a RESTful API: Full example
|
2022-07-12 18:00:04 +01:00
|
|
|
|
|
|
|
```js
|
2022-08-30 10:00:04 +01:00
|
|
|
const express = require("express");
|
2022-07-12 18:00:04 +01:00
|
|
|
const app = express(); // convention to name Express as the app
|
|
|
|
const port = process.env.PORT || 3000;
|
2022-08-30 10:00:04 +01:00
|
|
|
const Joi = require("joi");
|
|
|
|
const helmet = require("helmet");
|
|
|
|
const morgan = require("morgan");
|
|
|
|
const courses = require("./routes/courses");
|
2022-08-28 10:37:22 +01:00
|
|
|
|
|
|
|
// Routes
|
2022-08-30 10:00:04 +01:00
|
|
|
app.use("/api/courses", courses);
|
2022-07-12 18:00:04 +01:00
|
|
|
|
|
|
|
// Middlewear
|
|
|
|
app.use(express.json());
|
|
|
|
app.use(helmet());
|
|
|
|
|
|
|
|
const courses = [
|
|
|
|
{
|
|
|
|
id: 1,
|
2022-08-30 10:00:04 +01:00
|
|
|
name: "First course",
|
2022-07-12 18:00:04 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 2,
|
2022-08-30 10:00:04 +01:00
|
|
|
name: "Second course",
|
2022-07-12 18:00:04 +01:00
|
|
|
},
|
|
|
|
{
|
|
|
|
id: 3,
|
2022-08-30 10:00:04 +01:00
|
|
|
name: "Third course",
|
2022-07-12 18:00:04 +01:00
|
|
|
},
|
|
|
|
];
|
|
|
|
|
2022-08-30 10:00:04 +01:00
|
|
|
if (app.get("env") === "development") {
|
|
|
|
app.use(morgan("common"));
|
2022-07-12 18:00:04 +01:00
|
|
|
}
|
|
|
|
|
2022-08-28 10:37:22 +01:00
|
|
|
app.listen(port, () => console.log(`Listening on ${port}`));
|
|
|
|
|
2022-07-12 18:00:04 +01:00
|
|
|
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-07-12 18:00:04 +01:00
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
2022-08-30 10:00:04 +01:00
|
|
|
/**
|
|
|
|
* Note that the following request handlers would not be stored in `index.js` they would be in their dedicated routing file.
|
|
|
|
**/
|
|
|
|
|
2022-07-12 18:00:04 +01:00
|
|
|
// Return all data from API
|
2022-08-30 10:00:04 +01:00
|
|
|
courses.get("/", (req, res) => {
|
2022-07-12 18:00:04 +01:00
|
|
|
res.send(courses);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Return a specific value
|
2022-08-30 10:00:04 +01:00
|
|
|
courses.get("/:id", (req, res) => {
|
2022-07-12 18:00:04 +01:00
|
|
|
const course = courses.find((c) => c.id === parseInt(req.params.id));
|
2022-08-30 10:00:04 +01:00
|
|
|
if (!course) res.status(404).send("A course with the given ID was not found");
|
2022-07-12 18:00:04 +01:00
|
|
|
res.send(course);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Add a new course
|
2022-08-30 10:00:04 +01:00
|
|
|
courses.post("/", (req, res) => {
|
2022-07-12 18:00:04 +01:00
|
|
|
const schema = Joi.object({
|
|
|
|
name: Joi.string().min(3).required(),
|
|
|
|
});
|
|
|
|
|
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-07-12 18:00:04 +01:00
|
|
|
|
|
|
|
const course = {
|
|
|
|
id: courses.length + 1,
|
|
|
|
name: req?.body.name,
|
|
|
|
};
|
|
|
|
courses.push(course);
|
|
|
|
res.send(course);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Update a course
|
2022-08-30 10:00:04 +01:00
|
|
|
courses.put("/:id", (req, res) => {
|
2022-07-12 18:00:04 +01:00
|
|
|
const course = courses.find((c) => c.id === parseInt(req.params.id));
|
|
|
|
|
2022-08-30 10:00:04 +01:00
|
|
|
if (!course)
|
|
|
|
return res.status(404).send("A course with the given ID was not found");
|
|
|
|
const { error } = validateCourse(req.body);
|
2022-07-12 18:00:04 +01:00
|
|
|
|
2022-08-30 10:00:04 +01:00
|
|
|
if (error)
|
|
|
|
return error.details.map((joiErr) => res.status(400).send(joiErr.message));
|
2022-07-12 18:00:04 +01:00
|
|
|
|
|
|
|
course.name = req.body.name;
|
|
|
|
res.send(course);
|
|
|
|
});
|
|
|
|
|
|
|
|
// Delete a course
|
2022-08-30 10:00:04 +01:00
|
|
|
courses.delete("/:id", (req, res) => {
|
2022-07-12 18:00:04 +01:00
|
|
|
const course = courses.find((c) => c.id === parseInt(req.params.id));
|
2022-08-30 10:00:04 +01:00
|
|
|
if (!course)
|
|
|
|
return res.status(404).send("A course with the given ID was not found");
|
2022-07-12 18:00:04 +01:00
|
|
|
|
|
|
|
courses.indexOf(course);
|
|
|
|
courses.splice(index, 1);
|
|
|
|
|
|
|
|
res.send(course);
|
|
|
|
});
|
2022-08-28 10:37:22 +01:00
|
|
|
```
|