Class 24: Building a RESTful API with Express (CRUD - Read)
Now that we understand the principles of RESTful APIs, it's time to start building one! We'll begin with the "Read" operations of CRUD (Create, Read, Update, Delete), which are typically the simplest to implement.
For now, we'll use an in-memory JavaScript array to simulate a database. This allows us to focus purely on the Express.js API implementation without getting bogged down by database connections just yet.
Introduction to CRUD Operations
CRUD is an acronym that stands for the four basic operations of persistent storage:
-
C - Create: Adding new data. (Maps to HTTP
POST
) -
R - Read: Retrieving existing data. (Maps
to HTTP
GET
) -
U - Update: Modifying existing data. (Maps
to HTTP
PUT
orPATCH
) -
D - Delete: Removing data. (Maps to HTTP
DELETE
)
Almost every web application interacts with data using these four fundamental operations.
Designing API Endpoints for Resources
Following REST principles, we'll choose a resource to manage. Let's pick "Books" for our example.
Our base URL for the API will be /api/books
.
Operation | HTTP Method | Endpoint | Description |
---|---|---|---|
Get All Books | GET |
/api/books |
Retrieve a list of all books. |
Get Single Book | GET |
/api/books/:id |
Retrieve a single book by its ID. |
Create Book | POST |
/api/books |
Add a new book to the collection. |
Update Book | PUT |
/api/books/:id |
Update an existing book by its ID (full replacement). |
Delete Book | DELETE |
/api/books/:id |
Remove a book by its ID. |
In-Memory Data Storage (Dummy Data)
To simulate a database, we'll use a simple JavaScript array of objects. In a real application, this data would come from a persistent database like PostgreSQL, MongoDB, etc.
// server.js
const express = require('express');
const app = express();
const port = 3000;
// In-memory array to simulate our database
let books = [
{ id: '1', title: 'The Hitchhiker\'s Guide to the Galaxy', author: 'Douglas Adams', year: 1979 },
{ id: '2', title: '1984', author: 'George Orwell', year: 1949 },
{ id: '3', title: 'To Kill a Mockingbird', author: 'Harper Lee', year: 1960 }
];
// Middleware to parse JSON bodies (needed for POST/PUT/PATCH later)
app.use(express.json());
// Start the server
app.listen(port, () => {
console.log(`Server running at http://localhost:${port}`);
});
Using in-memory data is great for rapid prototyping and learning API concepts because it removes the complexity of database setup and operations.
Implementing GET All Resources
This endpoint will allow clients to retrieve a list of all books in our collection.
- Endpoint:
GET /api/books
- Response: A JSON array of book objects.
// server.js (continued)
// GET /api/books - Get all books
app.get('/api/books', (req, res) => {
if (books.length === 0) {
return res.status(200).json({ message: 'No books found.', data: [] });
}
res.status(200).json(books); // Send the array of books as JSON with 200 OK status
});
// ... app.listen() remains the same
Test it: Open your browser or API client (Postman/Insomnia) and go to http://localhost:3000/api/books. You should see the JSON array of books.
Implementing GET Single Resource by ID
This endpoint will allow clients to retrieve a specific book by its unique ID.
-
Endpoint:
GET /api/books/:id
-
Extracting Route Parameters: We use
req.params.id
to get the ID from the URL. -
Finding the Resource: We'll search our
books
array for a matching ID. -
Response:
-
If found: The book object as JSON with
200 OK
status. -
If not found: A JSON error message with
404 Not Found
status.
-
If found: The book object as JSON with
// server.js (continued)
// GET /api/books/:id - Get a single book by ID
app.get('/api/books/:id', (req, res) => {
const bookId = req.params.id; // Get the ID from the URL parameters
const book = books.find(b => b.id === bookId); // Find the book in our array
if (book) {
res.status(200).json(book); // Book found, send it
} else {
res.status(404).json({ message: `Book with ID ${bookId} not found.` }); // Book not found
}
});
// ... app.listen() remains the same
Test it:
- Go to http://localhost:3000/api/books/1. You should see the JSON for "The Hitchhiker's Guide to the Galaxy".
- Go to http://localhost:3000/api/books/99. You should receive a 404 Not Found error with a message.
Postman/Insomnia for API Testing (Basic)
While you can test GET requests directly in your browser, for POST, PUT, PATCH, and DELETE requests, you'll need an API client tool.
Two popular choices are:
- Postman: A comprehensive API development environment.
- Insomnia: A user-friendly API client.
You can download and install either of these for free. They allow you to:
- Select HTTP methods (GET, POST, PUT, DELETE, etc.).
- Enter request URLs.
- Add headers.
- Send request bodies (e.g., JSON).
- Inspect responses (status code, body, headers).
For the GET requests we just built, you can use Postman/Insomnia
to send requests to
http://localhost:3000/api/books
and
http://localhost:3000/api/books/1
and observe the
responses, including the status codes. This will be essential
for testing the Create, Update, and Delete operations in the
next classes.