Build a REST API with Node.js and Express
Build a bookshelf REST API with full CRUD operations using Node.js and Express.
Introduction
30 Second Summary
Every time you open a weather app, browse an online store, or scroll social media, your device is talking to a server behind the scenes. That invisible conversation follows a pattern called a REST API.
In this project, you will build a REST API server from scratch using Node.js and Express. Your API will manage a bookshelf collection, letting you add, view, update, and delete books through HTTP requests.
What You'll Build
A bookshelf REST API server running locally that handles all four CRUD operations (Create, Read, Update, Delete) for a collection of books, responding with JSON data.
By the end of this project, you'll have:
- A Node.js project with Express installed and configured to handle incoming requests.
- A working REST API with routes for creating, reading, updating, and deleting books.
- Tested API endpoints using curl commands from the terminal.
- Secret Mission: Add filtering and search functionality to your book collection API.
Are there any prerequisites?
This project assumes basic familiarity with JavaScript (variables, functions, objects, and arrays). You do not need any prior experience with servers or APIs.
Set Up Your Development Environment
Before you can build an API, you need a JavaScript runtime and a package manager on your machine. Node.js provides both: it runs JavaScript outside the browser, and it ships with npm for installing packages.
In this step, you'll install Node.js, create a new project folder, and install Express, the framework that will handle your API's HTTP requests.
In this step, get ready to:
- Install Node.js and open Cursor as your code editor.
- Create and initialize your project directory.
- Install Express and configure the project for ES modules.
Install Node.js and open Cursor
Node.js is the runtime that lets you execute JavaScript on your computer. It comes bundled with npm, the package manager you'll use to install Express.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Terminal and press Enter to open it.
- Check if Node.js is already installed by running this command:
node -v
✔️ I see version 18 or higher
You're all set. Your Node.js version is compatible with this project.
ⓧ I see an older version
You need Node.js 18 or higher for this project.
- Go to https://nodejs.org/en/download in your browser.
- Download and run the LTS installer for your operating system.
- Follow the installer prompts, accepting the defaults.
- Close and reopen your Terminal.
- Run node -v again to confirm you see v18 or higher.
ⓧ Command not found
Node.js is not installed on your machine yet.
- Go to https://nodejs.org/en/download in your browser.
- Click the download button for the LTS version (currently v24).
- Open the downloaded file and follow the installer prompts, accepting the defaults.
- Close and reopen your Terminal.
- Run node -v to confirm you see a version number starting with v18 or higher.
- Verify that npm is also available by running:
npm -v
You should see a version number printed. npm is included with Node.js, so if Node is installed correctly, npm is ready.
- Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
- Type Cursor and press Enter.
✔️ Cursor opened
You're ready to go. Keep Cursor open for now.
ⓧ I don't have Cursor installed
- Go to https://cursor.com/download in your browser.
- Click the download button for your operating system (macOS or Windows).
- Open the downloaded file. On macOS, drag Cursor into your Applications folder. On Windows, run the installer and follow the prompts.
- Open Cursor from your applications menu or search bar.
- Sign in with a free Cursor account when prompted.
Create your project and install Express
Every Node.js project lives in its own folder with a package.json file that tracks its name, version, and dependencies.
- Move to your Desktop by running this command:
cd ~/Desktop
- Create your project folder and move into it by running these commands:
mkdir bookshelf-api
cd bookshelf-api
- Initialize the project by running:
npm init -y
What does npm init -y do?
This command creates a package.json file with default values. The -y flag means "yes to all defaults" so you skip the interactive prompts.
The package.json file is the identity card of your project. It stores the project name, version, and the list of packages it depends on.
- Install Express by running:
npm install express@5.2.1
What is Express?
Express is a web framework for Node.js that makes it simple to define routes (URLs) and handle HTTP requests. It is the most widely-used Node.js framework for building APIs.
- Confirm everything was created by running:
ls
You should see node_modules, package.json, and package-lock.json listed in the output.
Don't see node_modules?
Make sure you ran npm install express@5.2.1 from inside the bookshelf-api folder. Run pwd to check your current directory.
If you see an error about npm not being found, revisit the Node.js installation tab above and make sure Terminal was closed and reopened after installing.
help me debug my npm install
Configure your project for ES modules
By default, Node.js uses the older CommonJS module system. Adding "type": "module" to your package.json enables the modern ES module syntax (import/export) that Express 5 recommends.
- Open the bookshelf-api folder in Cursor. Click File in the top menu bar.
- Click Open Folder.
- Navigate to your Desktop, select the bookshelf-api folder, then click Open.
- In the Explorer sidebar on the left, click package.json to open it.
- Find this line:
"main": "index.js",
- Change index.js to server.js, and add a new line directly below it with "type": "module", so those two lines now look like this:
"main": "server.js",
"type": "module",
- Save the file with Cmd+S (macOS) or Ctrl+S (Windows).
Why change main to server.js?
The main field tells Node.js which file is the entry point for your project. Since you'll write all your API code in server.js, updating this field now keeps your project metadata accurate.
Seeing red squiggly lines in package.json?
Make sure every line except the last property before a closing brace ends with a comma. JSON is strict about commas between properties.
help me fix my package.json syntax
✔️ Awesome, I've got everything!
Great. Double check you've saved package.json before moving on.
ⓧ I'd like to double check the full code
Your package.json should look like this:
{
"name": "bookshelf-api",
"version": "1.0.0",
"description": "",
"main": "server.js",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "5.2.1"
}
}
Your development environment is ready. Next up, you'll create your first Express server and make it respond to HTTP requests.
Create Your First Express Server
Your development environment is ready. Now it's time to write the code that actually does something.
Every web application needs a server that listens for incoming requests and sends back responses. In this step, you'll create your server file, wire up Express to handle requests, and confirm everything works by hitting your server with a real HTTP request.
In this step, get ready to:
- Create a server file and configure Express to parse JSON.
- Add a welcome route that responds with a JSON message.
- Start your server and test it with a real HTTP request.
Create the server file with Express
Your server.js file is the entry point for your API. It imports Express, sets up middleware to understand incoming data, and starts listening for requests.
- In Cursor, open package.json from the Explorer sidebar.
- Find these two lines:
"description": "",
"test": "echo \"Error: no test specified\" && exit 1"
- Replace the description value with a project summary, and replace the test script with a start script, so those lines now look like this:
"description": "A REST API for managing a book collection",
"start": "node server.js"
What does the start script do?
The start script lets you run npm start instead of typing node server.js every time. It's a standard convention in Node.js projects that other developers and deployment tools expect to find.
- Save package.json by pressing Cmd+S (macOS) or Ctrl+S (Windows).
✔️ Awesome, I've got everything!
Great. Double check you've saved package.json before moving on.
ⓧ I'd like to double check the full code
{
"name": "bookshelf-api",
"version": "1.0.0",
"description": "A REST API for managing a book collection",
"main": "server.js",
"type": "module",
"scripts": {
"start": "node server.js"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "5.2.1"
}
}
- Create a new file called server.js in the root of your bookshelf-api folder by clicking the new file icon in the Explorer sidebar.
- Add the following code to set up your Express server skeleton:
import express from 'express';
const app = express();
const port = 3000;
// Middleware to parse JSON request bodies
app.use(express.json());
// Start the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
What does this code do?
- import express from 'express' loads the Express library using ES module syntax (enabled by the "type": "module" setting in your package.json).
- const app = express() creates your application instance. Every route and piece of configuration attaches to this app object.
- app.use(express.json()) adds middleware that automatically reads JSON from incoming request bodies and makes it available as req.body.
- app.listen(port, callback) tells the server to start accepting connections on port 3000. The callback prints a confirmation message.
- Save server.js.
- Confirm the file appears in your Explorer sidebar next to package.json.
Don't see server.js in the sidebar?
- Make sure you created the file inside the bookshelf-api folder, not inside node_modules or a subfolder.
- Check that the filename is exactly server.js with no extra spaces or uppercase letters.
Why isn't my server.js file showing up?
Add a welcome route
A route tells your server how to respond when someone visits a specific URL path. You'll add a root route at / that sends back a welcome message as JSON.
- In server.js, find the comment that says // Start the server.
- Add the following route code directly above that comment:
// Root route
app.get('/', (req, res) => {
res.json({ message: 'Welcome to the Bookshelf API' });
});
What does this route do?
- app.get('/', ...) registers a handler for GET requests to the root path (/).
- req is the incoming request object. res is the response object you use to send data back.
- res.json(...) sends a JSON response and automatically sets the correct Content-Type header.
- Save server.js. You won't see a visible change yet. The next substep starts the server so you can test your route.
✔️ Awesome, I've got everything!
Great. Make sure your route sits between the app.use(express.json()) line and the app.listen block.
ⓧ I'd like to double check the full code
import express from 'express';
const app = express();
const port = 3000;
// Middleware to parse JSON request bodies
app.use(express.json());
// Root route
app.get('/', (req, res) => {
res.json({ message: 'Welcome to the Bookshelf API' });
});
// Start the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Start your server and test it
Your server file is complete. Time to start it up and confirm it responds to a real HTTP request.
- Open a terminal in Cursor by pressing Ctrl+` (backtick key, same shortcut on macOS and Windows).
- Start your server by running this command:
node server.js
- You should see this message in your terminal:
Server is running on http://localhost:3000
Seeing an error instead?
- If you see SyntaxError: Cannot use import statement, confirm that package.json contains "type": "module".
- If you see Cannot find module 'express', make sure your terminal is inside the bookshelf-api folder where node_modules lives.
- If the port is already in use, close any other servers running on port 3000, or restart your terminal and try again.
Help me debug my Express server startup error.
Your server is now running, but it occupies that terminal. You need a second terminal to send it a request.
- Open a second terminal by clicking the + icon in the terminal panel (or press Cmd+Shift+` on macOS / Ctrl+Shift+` on Windows).
- Test your server by running this command:
curl http://localhost:3000
- You should see this JSON response in your terminal:
{"message":"Welcome to the Bookshelf API"}
What is curl?
curl is a command-line tool for making HTTP requests. It comes pre-installed on macOS and most Linux systems. Think of it as a bare-bones web browser that prints the raw response instead of rendering a page.
When you run curl http://localhost:3000, it sends a GET request to your server and prints whatever your server sends back.
Not seeing the JSON response?
- Make sure the first terminal still shows the running server message. If you accidentally closed it, run node server.js again.
- Check that you typed the URL exactly, including http:// at the start.
- On Windows, if curl is not recognized, try using PowerShell instead of Command Prompt.
Help me troubleshoot my curl request to localhost.
Your server is alive and responding to requests. Next up, you'll build the routes that let you create, read, update, and delete books from your collection.
Build the Read and Create Endpoints
Your server is up and running, but all it can do right now is greet visitors at the root route. A real REST API needs to serve actual data.
In this step, you'll create a collection of books stored in memory and build the routes that let clients read from it and add to it. These are the R and C in CRUD (Create, Read, Update, Delete).
In this step, get ready to:
- Create an in-memory data store with sample books.
- Build GET routes to retrieve all books and a single book by ID.
- Build a POST route to add new books to the collection.
Add the in-memory book collection
Your API needs data to serve. Instead of connecting to a database, you'll store books in a JavaScript array that lives in your server's memory.
- In server.js in Cursor, find the line that says app.use(express.json());.
- Below that line, add the following data store code:
// In-memory data store
let books = [
{ id: 1, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
{ id: 2, title: '1984', author: 'George Orwell' },
{ id: 3, title: 'To Kill a Mockingbird', author: 'Harper Lee' }
];
let nextId = 4;
What does this code do?
The books array holds your sample book objects. Each book has three properties: id (a unique number), title, and author.
The nextId variable tracks which ID to assign to the next book that gets created. It starts at 4 because the three sample books already use IDs 1, 2, and 3.
You won't see a change yet. The next chunk adds a route that exposes this data.
Add the GET /books route
Now you need a route that returns the entire book collection when a client sends a GET request to /books.
- In server.js, find the root route (the app.get('/', ...) block).
- Below the root route's closing });, add the following route:
// GET all books
app.get('/books', (req, res) => {
res.json(books);
});
What does this code do?
When a client sends a GET request to /books, Express matches the path and runs your handler function.
The res.json(books) call converts the books array into JSON and sends it back to the client with a 200 status code automatically.
- Save server.js.
- Switch back to the terminal where your server is running.
- Press Ctrl+C to stop the server, then restart it by running:
node server.js
- Open a second terminal window by pressing Ctrl+Shift+` (backtick) in Cursor.
- Test the endpoint by running:
curl http://localhost:3000/books
You should see the three sample books returned as a JSON array in your terminal.
Don't see the books array?
- Make sure you stopped the old server with Ctrl+C before restarting. The old process won't pick up your code changes.
- Check that your books array is placed ABOVE the root route in server.js. JavaScript reads top to bottom, so the data must be defined before a route tries to use it.
- Confirm you saved server.js before restarting. Unsaved changes won't be included when Node.js reads the file.
Help me debug why curl http://localhost:3000/books is not returning my books array.
Add the GET /books/:id route
Returning all books is useful, but clients also need to fetch a single book by its ID. This requires a route parameter.
- In server.js, add the following route below the GET /books route you just created:
// GET a single book by ID
app.get('/books/:id', (req, res) => {
const id = parseInt(req.params.id);
const book = books.find(b => b.id === id);
if (!book) {
return res.status(404).json({ error: 'Book not found' });
}
res.json(book);
});
What does this code do?
The :id in the route path is a route parameter. Express captures whatever value the client puts in that URL segment and stores it in req.params.id.
Since URL parameters arrive as strings, parseInt() converts it to a number so it can match against the numeric id in each book object.
If no book matches, the route responds with a 404 status code and an error message. This tells the client the resource they asked for does not exist.
- Save server.js, stop the server with Ctrl+C, and restart it by running:
node server.js
- In your second terminal, test fetching a single book by running:
curl http://localhost:3000/books/1
You should see just The Great Gatsby book object returned.
- Now test the 404 error by requesting a book that does not exist:
curl http://localhost:3000/books/99
You should see {"error":"Book not found"} returned with a 404 status.
Getting the full books array instead of one book?
- Check that your new route uses '/books/:id' with a colon before id. Without the colon, Express treats it as a literal path segment.
- Make sure the '/books/:id' route is placed AFTER the '/books' route. Express matches routes in order, so the more specific path should come second.
Help me figure out why my GET /books/:id route isn't working correctly.
Add the POST /books route
Reading data is only half the story. Your API also needs to accept new books from clients. A POST request sends data in the request body, and your route will use that data to create a new book.
- In server.js, add the following route below the GET /books/:id route:
// POST a new book
app.post('/books', (req, res) => {
const { title, author } = req.body;
if (!title || !author) {
return res.status(400).json({ error: 'Title and author are required' });
}
const newBook = { id: nextId++, title, author };
books.push(newBook);
res.status(201).json(newBook);
});
What does this code do?
The const { title, author } = req.body line pulls the title and author fields out of the incoming JSON request body. This works because the express.json() middleware you added earlier parses the raw JSON into a JavaScript object.
The validation check returns a 400 (Bad Request) status if either field is missing. This prevents incomplete books from being added to the collection.
The nextId++ assigns the current value of nextId as the new book's ID, then increments it by one for the next creation. Finally, res.status(201).json(newBook) sends back the newly created book with a 201 (Created) status code.
- Save server.js, stop the server with Ctrl+C, and restart it by running:
node server.js
- In your second terminal, create a new book by running:
curl -X POST -H "Content-Type: application/json" -d '{"title":"Dune","author":"Frank Herbert"}' http://localhost:3000/books
You should see the new book returned with id: 4 and a 201 status.
- Verify the book was added to the collection by running:
curl http://localhost:3000/books
You should now see four books in the array, including the Dune book you just added.
Getting an error when sending the POST request?
- Make sure the -H "Content-Type: application/json" header is included. Without it, Express won't parse the body as JSON.
- Check that the -d flag uses single quotes around the JSON object and double quotes inside it. Mixing these up causes parsing errors.
- If you see {"error":"Title and author are required"}, confirm that app.use(express.json()) is still near the top of your file, before any routes.
Help me debug why my POST request to /books is failing.
✔️ Awesome, I've got everything!
Great. Double check you've saved server.js and your server is running.
ⓧ I'd like to double check the full code
Here is the complete server.js file at this point:
import express from 'express';
const app = express();
const port = 3000;
// Middleware to parse JSON request bodies
app.use(express.json());
// In-memory data store
let books = [
{ id: 1, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
{ id: 2, title: '1984', author: 'George Orwell' },
{ id: 3, title: 'To Kill a Mockingbird', author: 'Harper Lee' }
];
let nextId = 4;
// Root route
app.get('/', (req, res) => {
res.json({ message: 'Welcome to the Bookshelf API' });
});
// GET all books
app.get('/books', (req, res) => {
res.json(books);
});
// GET a single book by ID
app.get('/books/:id', (req, res) => {
const id = parseInt(req.params.id);
const book = books.find(b => b.id === id);
if (!book) {
return res.status(404).json({ error: 'Book not found' });
}
res.json(book);
});
// POST a new book
app.post('/books', (req, res) => {
const { title, author } = req.body;
if (!title || !author) {
return res.status(400).json({ error: 'Title and author are required' });
}
const newBook = { id: nextId++, title, author };
books.push(newBook);
res.status(201).json(newBook);
});
// Start the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Your API can now read and create books. Next up, you'll complete the full set of CRUD operations by adding the ability to update and delete books from the collection.
Build the Update and Delete Endpoints
Your API can already fetch books and add new ones to the collection. The final piece is giving users the power to update and remove books.
PUT and DELETE are the last two HTTP methods you need. Together with GET and POST, they complete the four CRUD operations that form the backbone of any REST API.
In this step, get ready to:
- Add a PUT route to update existing books.
- Add a DELETE route to remove books from the collection.
- Test all four CRUD endpoints with curl.
Add the PUT route to update books
A PUT request lets clients send updated data for an existing resource. Your route needs to find the book, apply the changes, and send back the updated version.
- In server.js, find the comment // Start the server near the bottom of your file.
- Add the following code above that line:
// PUT (update) a book by ID
app.put('/books/:id', (req, res) => {
const id = parseInt(req.params.id);
const book = books.find(b => b.id === id);
if (!book) {
return res.status(404).json({ error: 'Book not found' });
}
const { title, author } = req.body;
if (title) book.title = title;
if (author) book.author = author;
res.json(book);
});
What does this code do?
- parseInt(req.params.id) converts the URL parameter from a string to a number so it matches the numeric IDs in your books array.
- The if (title) and if (author) checks let the client update one field without erasing the other.
- res.json(book) sends back the updated book so the client can confirm the changes took effect.
- Save server.js.
You won't see a change yet. The testing substep will confirm this route works.
Seeing a syntax error when you restart later?
- Make sure the new code sits between the closing }); of the POST route and the // Start the server comment.
- Check for a missing closing parenthesis or curly brace at the end of the route.
Help me fix a syntax error in my Express PUT route
Add the DELETE route to remove books
A DELETE request removes a resource entirely. Instead of returning the deleted data, the standard practice is to respond with a 204 (No Content) status.
- Still in server.js, add the following code below the PUT route you just wrote (and above // Start the server):
// DELETE a book by ID
app.delete('/books/:id', (req, res) => {
const id = parseInt(req.params.id);
const index = books.findIndex(b => b.id === id);
if (index === -1) {
return res.status(404).json({ error: 'Book not found' });
}
books.splice(index, 1);
res.status(204).end();
});
What does this code do?
- findIndex returns the position of the book in the array, or -1 if no match is found.
- splice(index, 1) removes exactly one element at that position from the array.
- Status 204 means "No Content." The deletion worked, but there is nothing to send back. .end() closes the response without a body.
- Save server.js.
You won't see a change yet. The next substep tests both new routes together.
Seeing 'Cannot find module' or a crash?
- Double-check that you have not accidentally deleted the import express from 'express'; line at the top of the file.
- Make sure the DELETE route ends with }); before the // Start the server comment.
Help me fix a crash in my Express server after adding a DELETE route
✔️ Awesome, I've got everything!
Great. Double check you have saved server.js before moving on to testing.
ⓧ I'd like to double check the full code
import express from 'express';
const app = express();
const port = 3000;
// Middleware to parse JSON request bodies
app.use(express.json());
// In-memory data store
let books = [
{ id: 1, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' },
{ id: 2, title: '1984', author: 'George Orwell' },
{ id: 3, title: 'To Kill a Mockingbird', author: 'Harper Lee' }
];
let nextId = 4;
// Root route
app.get('/', (req, res) => {
res.json({ message: 'Welcome to the Bookshelf API' });
});
// GET all books
app.get('/books', (req, res) => {
res.json(books);
});
// GET a single book by ID
app.get('/books/:id', (req, res) => {
const id = parseInt(req.params.id);
const book = books.find(b => b.id === id);
if (!book) {
return res.status(404).json({ error: 'Book not found' });
}
res.json(book);
});
// POST a new book
app.post('/books', (req, res) => {
const { title, author } = req.body;
if (!title || !author) {
return res.status(400).json({ error: 'Title and author are required' });
}
const newBook = { id: nextId++, title, author };
books.push(newBook);
res.status(201).json(newBook);
});
// PUT (update) a book by ID
app.put('/books/:id', (req, res) => {
const id = parseInt(req.params.id);
const book = books.find(b => b.id === id);
if (!book) {
return res.status(404).json({ error: 'Book not found' });
}
const { title, author } = req.body;
if (title) book.title = title;
if (author) book.author = author;
res.json(book);
});
// DELETE a book by ID
app.delete('/books/:id', (req, res) => {
const id = parseInt(req.params.id);
const index = books.findIndex(b => b.id === id);
if (index === -1) {
return res.status(404).json({ error: 'Book not found' });
}
books.splice(index, 1);
res.status(204).end();
});
// Start the server
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Test all endpoints with curl
Your server needs to restart to pick up the new routes. Then you can fire off curl commands to prove all four CRUD operations work.
- Switch to the terminal where your server is running.
- Press Ctrl+C to stop the server.
- Restart the server by running:
node server.js
- You should see Server is running on http://localhost:3000 in your terminal.
- Switch to your second terminal window for curl commands.
- Update book 2's title by running this PUT request:
curl -X PUT -H "Content-Type: application/json" -d '{"title":"Nineteen Eighty-Four"}' http://localhost:3000/books/2
You should see the updated book returned with the new title and the original author preserved:
{"id":2,"title":"Nineteen Eighty-Four","author":"George Orwell"}
Why did the author stay the same?
Your PUT route only updates fields that are provided in the request body. Since you only sent a new title, the author field remained unchanged.
- Delete book 3 by running this DELETE request:
curl -X DELETE http://localhost:3000/books/3
You should see no response body. The 204 status means the deletion succeeded with nothing to return.
- Verify the changes persisted by fetching all books:
curl http://localhost:3000/books
You should see only two books. Book 2 has its updated title, and book 3 is gone.
[{"id":1,"title":"The Great Gatsby","author":"F. Scott Fitzgerald"},{"id":2,"title":"Nineteen Eighty-Four","author":"George Orwell"}]
Seeing 'Connection refused'?
- Make sure you restarted the server after saving your changes. The old process does not pick up new code automatically.
- Check that Server is running on http://localhost:3000 appears in the server terminal before you run curl.
- If the port is still in use, wait a few seconds and try node server.js again.
Help me fix connection refused when testing my Express API with curl
Secret mission
Add Filtering and Search
Your API can create, read, update, and delete books. But what if your collection grows to hundreds of entries? Add query parameter filtering so users can search by title or author without scrolling through everything.
Clean Up Your Resources
Clean Up Your Resources
Decide whether to keep your resources running, pause them to come back later, or delete them entirely.
This project runs entirely locally, so there are no ongoing costs.
Resources you used:
- The running Node.js server process on port 3000.
- The bookshelf-api project folder on your Desktop (contains server.js, package.json, and node_modules).
Keep everything running
No action needed. Choose this if you are still actively building or plan to extend your API right away.
- Your server keeps running on port 3000 until you close the terminal or restart your computer.
- Your project files remain on the Desktop, ready to edit whenever you open Cursor again.
Pause - I'll come back to this later
Shut down the running server to free up port 3000. Your project files stay on your Desktop for next time.
- Switch to the terminal window where your server is running.
- Press Ctrl+C to stop the server process.
- To restart later, open a terminal, navigate to your bookshelf-api folder, and run node server.js.
Delete - I don't want to use this again
Remove all project files and stop the server. This frees up disk space and port 3000.
- Switch to the terminal window where your server is running and press Ctrl+C to stop it.
- Delete the project folder by running the command for your operating system:
macOS
rm -rf ~/Desktop/bookshelf-api
Windows
rmdir /s /q %USERPROFILE%\Desktop\bookshelf-api
- Confirm the folder is gone by running:
ls ~/Desktop
You should no longer see bookshelf-api in the output.
Nice Work!
Nice Work!
You just built a fully functional REST API server from scratch using Node.js and Express. This is the same pattern that powers the backends of web apps, mobile apps, and services you use every day.
You've learned how to:
- Build a REST API server with Node.js and Express that handles all four CRUD operations (GET, POST, PUT, DELETE) with appropriate HTTP status codes.
- Design RESTful routes with URL parameters, request body parsing via express.json() middleware, and proper error handling for missing resources.
- Test API endpoints from the command line using curl to send HTTP requests and verify JSON responses.
- Secret Mission: Added filtering and search functionality using query parameters for case-insensitive partial matching on book titles and authors.
Ready to quiz yourself?