4. Creating a REST API in Express
1. Setting Up an Express Application
- Install Express:
npm init -y npm install express
- Create a
index.js
file, which will be the main entry point of your app.
const express = require('express');
const app = express();
const port = 3000;
app.listen(port, () => {
console.log(`Server running on http://localhost:${port}`);
});
- This is the same as any other express app we’ve created so far
2. Defining Routes (Endpoints)
- Routes (or endpoints) define the actions you can perform on a resource using a specific HTTP method.
- Express makes it easy to define these routes.
- Example: Defining a route for getting all books in the library.
app.get('/books', (req, res) => { res.json(books); // Sends the list of books });
- The
app.get
indicates that the route we’re defining will respond toGET
requests- There is also
app.delete
forDELETE
requests,app.post
forPOST
requests andapp.put
forPUT
requests
- There is also
- The
/books
parameter indicates that this is for anyGET
requests directed to/books
- Then we’re sending back a list of books as a JSON object
- If we wanted to handle a
POST
request, we’d declare a new route withapp.post
- The
3. Handling Incoming Data in HTTP Requests
- As mentioned earlier, in a REST API each request often has some form of data associated with it and we need to make sure we can access it
Query Parameters
- As discussed previously, query parameters are used to send data when using a
GET
requestGET
requests don’t have a body, so we can’t put the data there
- Query parameters are added to the end of a
URL
after a?
and are used to filter data that the server might otherwise send back - In Express, we can access the query parameters via the
query
object on therequest
- Example: Suppose a user wants to search for books by their publish year, they want to send a request like
GET /books?publishYear=2024
app.get('/books', (req, res) => { const publishYear = req.query.publishYear; // Extract the 'publishYear' query parameter let filteredBooks = books; if (publishYear) { //If the publish year is valid, filter the books filteredBooks = books.filter((book) => book.publishYear === publishYear); } res.json(filteredBooks); // Send the filtered list of books });
- First, we extract the
publishYear
query parameter viareq.query.publishYear
- Second, if the
publishYear
is valid, we filter the books based on the year the book was published
- First, we extract the
URL Parameters
URL parameters are part of the URL path and used to reference specific resources.
- These are different from query parameters because they are embedded within the URL path itself rather than being added at the end.
- They are often used in routes like
GET /books/:id
where:id
is a placeholder for the actual book ID.
In Express, URL parameters are accessed via the
params
object on therequest
.Sending Data Back: We typically send the response back in JSON format using
res.json()
to send structured data back to the client.When to Use URL Parameters vs. Query Parameters:
- URL parameters are used when the data is necessary to identify or target a specific resource.
- Example: To retrieve or update a specific book by its ID (
GET /books/:id
orPUT /books/:id
).
- Example: To retrieve or update a specific book by its ID (
- Query parameters are used when filtering or searching through a list of resources.
- Example: To search for books published in a particular year (
GET /books?publishYear=2024
).
- Example: To search for books published in a particular year (
- Key Difference: URL parameters are mandatory to specify a particular resource, whereas query parameters are optional and used to modify a broader result set.
- URL parameters are used when the data is necessary to identify or target a specific resource.
Example: Suppose a user wants to get details of a specific book with the ID of 3, they send a request like
GET /books/3
app.get('/books/:id', (req, res) => { const bookId = parseInt(req.params.id); // Extract the 'id' parameter from the URL const book = books.find((book) => book.id === bookId); // Find the book by its ID if (!book) { return res.status(404).json({ message: 'Book not found' }); // If no book is found, send a 404 error } res.json(book); // Send the found book in JSON format });
- First, we extract the
id
parameter viareq.params.id
. - Second, we find the corresponding book by its ID and return the book details with
res.json(book)
, or a 404 error if the book is not found.
- First, we extract the
Request Body
- The request body is used in POST and PUT requests, where the client sends data to create or update resources.
- For example, when adding a new book to the library, the data for the new book is sent in the body of the request.
- The body typically contains JSON data, and in Express, we access it via
req.body
. - Note: You need to use the
express.json()
middleware to parse JSON bodies.
- Middleware for Parsing JSON:
- Express does not automatically parse the body of a request. We need to use the express.json() middleware to enable the server to read and parse JSON data in incoming requests.
- The middleware converts the raw request body into a JavaScript object, allowing us to easily access the data via req.body.
- Without this middleware,
req.body
would be undefined, and the server wouldn’t be able to access the incoming data.
- Example: Suppose a user wants to add a new book to the library, they send a request like
POST /books
with the book data in the body:app.use(express.json()); // Add some Express Middleware to parse JSON request bodies app.post('/books', (req, res) => { const { title, author, publishYear } = req.body; // Extract the data from the request body const newBook = { id: books.length + 1, // Generate a new ID title, author, publishYear }; books.push(newBook); // Add the new book to the list of books res.status(201).json(newBook); // Return the newly created book with a 201 status });
- First, we extract the data (
title
,author
, andpublishYear
) from the request body usingreq.body
. - Second, we create a new book object and add it to the
books
array, then return the new book with a201 Created
status.
- First, we extract the data (