Build a REST API with Node.js

Build a REST API server with Express that handles CRUD operations.

Introduction

30 Second Summary

Every time you open an app to check the weather, browse a menu, or scroll through posts, your app is talking to a server behind the scenes. That server decides what data to send back based on what you asked for.

In this project, you will build your own server that manages a collection of books. You'll create endpoints that let anyone add, view, update, and delete books using simple HTTP requests.

What You'll Build

A REST API server built with Node.js and Express that handles CRUD operations for a book collection.

By the end of this project, you'll have:

  • A Node.js project with Express installed and configured to parse JSON request bodies.
  • A complete set of RESTful endpoints covering Create, Read, Update, and Delete operations using proper HTTP methods and status codes.
  • Tested API responses using curl commands in the terminal to confirm each endpoint works.
  • Secret Mission: Add a search endpoint that lets users filter books by author or title.

Are there any prerequisites?

You should be comfortable with basic JavaScript concepts like variables, functions, arrays, and objects. No backend or server experience is needed.

Before We Start

Before you can build your REST API, you need a few tools in place. Node.js runs JavaScript outside the browser, and Express is the framework that handles incoming requests and sends responses.

In this step, you will install Node.js, create a project folder, and add Express as a dependency. By the end, your environment will be ready for building API endpoints.

In this step, get ready to:
  • Install Node.js and verify it works in your terminal.
  • Create and initialize your project folder.
  • Install Express as a project dependency.
Install Node.js

Node.js is the JavaScript runtime that lets you run code on your computer (outside a web browser). It comes with npm, a package manager that downloads libraries like Express for your project.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Terminal (macOS) or PowerShell (Windows) and press Enter to open it.
  • Check if Node.js is already installed by running this command:
node --version

✔️ I see version 22 or higher

Node.js is ready to go. Move on to the next substep.

ⓧ I see an older version

Your installed version is below 22, which is the minimum for this project. You need to upgrade to Node.js 22 LTS.

  • Go to https://nodejs.org in your browser.
  • Download the LTS version (v22).
  • Run the installer and accept all defaults.
  • Close your terminal completely, then reopen it.
  • Run node --version again to confirm it now shows v22 or higher.

Why close and reopen the terminal?

Your terminal loads the path to Node.js when it first opens. After installing a new version, you need a fresh terminal session to pick up the updated path.

ⓧ Command not found

Node.js is not installed on your machine yet. Follow these steps to install it.

  • Go to https://nodejs.org in your browser.
  • Click the LTS download button (v22).
  • Run the downloaded installer and accept all the default options.
  • Close your terminal completely, then reopen it.
  • Run node --version again. You should now see a version number starting with v22.
  • Confirm npm is also available by running:
npm --version

You should see a version number printed. npm is installed automatically alongside Node.js.

npm command not found?

If node --version works but npm --version does not, try closing and reopening your terminal. If the problem persists, reinstall Node.js from the official site.

Help me troubleshoot why npm is not recognized in my terminal.

Create your project folder and initialize it

Every Node.js project lives in its own folder with a package.json file that tracks project details 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 book-api
cd book-api
  • Initialize your project by running:
npm init -y

What does this command do?

The -y flag tells npm to accept all the defaults without asking you questions. It creates a package.json file with your project name set to the folder name (book-api), version 1.0.0, and a default entry point of index.js.

  • Confirm the file was created by running:
ls

You should see package.json listed in the output.

Don't see package.json?

Make sure you ran cd book-api before running npm init -y. The file is created in whatever folder your terminal is currently inside.

Help me figure out why package.json was not created in my book-api folder.

Install Express and open your project

Express is a lightweight framework that makes it simple to define routes and handle HTTP requests. Installing it adds the library to your project's node_modules folder and records it as a dependency in package.json.

  • Install Express by running:
npm install express

What does this command do?

This downloads the Express package from the npm registry and saves it inside a node_modules folder in your project. It also adds an entry under dependencies in your package.json so anyone else working on this project can install the same packages.

  • Confirm Express was installed by running:
ls

You should now see node_modules, package.json, and package-lock.json in the output.

Seeing permission errors?

On macOS, if you see a permission error, try running the command with sudo in front. On Windows, make sure you opened PowerShell as an administrator.

Help me fix permission errors when running npm install.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type Cursor (or VS Code) and press Enter to open it.
  • Click File in the top menu bar.
  • Click Open Folder.
  • Navigate to your Desktop, select the book-api folder, and click Open.

You should see package.json and the node_modules folder in the file explorer sidebar on the left.

✔️ Awesome, I've got everything!

Great. Double check that you see package.json, package-lock.json, and the node_modules folder in your project.

ⓧ I'd like to double check the full code

Open package.json in your editor. It should look similar to this (your version numbers may differ slightly):

{
  "name": "book-api",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "express": "^5.2.1"
  }
}

The important part is that express appears under dependencies. The exact version number after the ^ may be different on your machine.

Your development environment is ready. Next up, you will create the server file and write your first API endpoint.

Create Your Server and First Route

Your development environment is ready with Express installed. Now it's time to write the code that turns your empty project folder into a working API server.

Every REST API needs a server that listens for incoming requests and responds with data. In this step, you'll create a server file, configure Express to handle requests, and build your first endpoint that returns a list of books as JSON.

In this step, get ready to:
  • Create server.js with Express configured and sample book data.
  • Build your first GET endpoint that returns all books as JSON.
  • Start the server and test it with a curl command.
Create server.js with the basic Express server

Your API needs a single file that does four things: imports Express, configures it to understand JSON, stores some sample book data, and defines a route that serves that data.

  • In Cursor (or VS Code), right-click in the Explorer sidebar on the left.
  • Select New File.
  • Type server.js and press Enter.

This creates the file inside your book-api folder. You'll add code in three chunks below.

  • Set up Express and configure the JSON-parsing middleware by pasting this code into server.js:
const express = require('express');
const app = express();
const PORT = 3000;

// Middleware to parse JSON request bodies
app.use(express.json());

What does this code do?

  • require('express') loads the Express library you installed earlier.
  • express() creates your app instance. Every route you define goes through this object.
  • PORT stores the port number your server will listen on.
  • express.json() is middleware that automatically converts incoming JSON request bodies into JavaScript objects you can work with.

What is middleware?

Middleware is code that runs between receiving a request and sending a response. Think of it as a processing step your request passes through before reaching your route handler.

express.json() is one of Express's built-in middleware functions. Without it, your server wouldn't understand JSON data sent in POST or PUT requests.

You won't see a change yet. The next chunk adds the book data your server will serve.

  • Add the sample book data below the app.use(express.json()) line:
// Sample data - our "database" of books
let books = [
  { id: 1, title: '1984', author: 'George Orwell' },
  { id: 2, title: 'To Kill a Mockingbird', author: 'Harper Lee' },
  { id: 3, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' }
];

let nextId = 4;

What does this code do?

  • books is a JavaScript array that acts as your in-memory database. Each book has an id, title, and author.
  • nextId tracks the next ID to assign when a new book is created. Since you have 3 books starting with IDs 1-3, the next one gets ID 4.
  • let (instead of const) allows the array and counter to change as books are added or removed.

You won't see a change yet. The next chunk adds the route and starts the server.

  • Add the GET route and server startup code below the let nextId = 4; line:
// GET /books - Get all books
app.get('/books', (req, res) => {
  res.json(books);
});

// Start the server
app.listen(PORT, () => {
  console.log(`Book API server running at http://localhost:${PORT}`);
});

What does this code do?

  • app.get('/books', ...) registers a route that responds to GET requests at the /books path.
  • req is the incoming request object. res is the response object you use to send data back.
  • res.json(books) sends the entire books array as a JSON response with a 200 status code automatically.
  • app.listen(PORT, ...) starts the server and prints a confirmation message once it's ready to accept requests.
  • Save server.js by pressing Cmd+S (macOS) or Ctrl+S (Windows).
  • Confirm server.js appears in the Explorer sidebar alongside package.json and the node_modules folder.

Don't see server.js in the sidebar?

  • Make sure you created the file inside the book-api folder, not inside node_modules or a subfolder.
  • Check that you typed the filename as server.js (all lowercase, no spaces).

Help me find where my server.js file ended up

✔️ Awesome, I've got everything!

Great. Double check you've saved your file before moving on.

ⓧ I'd like to double check the full code

Here's the complete server.js file so far:

const express = require('express');
const app = express();
const PORT = 3000;

// Middleware to parse JSON request bodies
app.use(express.json());

// Sample data - our "database" of books
let books = [
  { id: 1, title: '1984', author: 'George Orwell' },
  { id: 2, title: 'To Kill a Mockingbird', author: 'Harper Lee' },
  { id: 3, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' }
];

let nextId = 4;

// GET /books - Get all books
app.get('/books', (req, res) => {
  res.json(books);
});

// Start the server
app.listen(PORT, () => {
  console.log(`Book API server running at http://localhost:${PORT}`);
});
Start your server and test it

Your server file is ready. Now you'll start it and confirm it responds to requests.

  • Open a terminal in Cursor (or VS Code) 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:

Book API server running at http://localhost:3000

What does this message mean?

Your server is now running and listening on port 3000. It will keep running until you stop it with Ctrl+C. While it runs, it can receive and respond to HTTP requests.

Seeing an error instead?

  • If you see SyntaxError, check server.js for missing commas, brackets, or backticks. Compare your code against the full file in the double-check tab above.
  • If you see a message about the port already being in use, another process is using port 3000. Close any other servers or apps that might be running, then try again.
  • If you see Cannot find module 'express', make sure you're in the book-api folder. Run npm install express again.

Help me fix the error I'm seeing when starting my Express server

Now you'll test your endpoint. You need a second terminal because the first one is busy running the server.

  • Open a new terminal tab by clicking the + icon in the terminal panel (next to the existing terminal tab).
  • Test your GET /books endpoint by running this command:
curl http://localhost:3000/books

You should see your books array returned as JSON in the terminal:

[{"id":1,"title":"1984","author":"George Orwell"},{"id":2,"title":"To Kill a Mockingbird","author":"Harper Lee"},{"id":3,"title":"The Great Gatsby","author":"F. Scott Fitzgerald"}]

What just happened?

You sent an HTTP GET request to your server at http://localhost:3000/books. Your server matched the /books path to the route you defined, ran the handler function, and sent back the books array as JSON.

This is the request/response cycle in action. Every API endpoint follows this same pattern.

Seeing 'Connection refused'?

  • Make sure your server is still running in the first terminal tab. You should see the startup message there.
  • If you accidentally closed the server, switch back to the first terminal tab and run node server.js again.

Help me figure out why curl can't connect to my server

Your first API endpoint is live. Next up, you'll add more routes to fetch a single book and create new ones.

Add Read and Create Endpoints

Your server is up and running with an endpoint that returns all books at once. That's a great start, but a real API needs more flexibility.

In this step, you'll add two essential capabilities: looking up a single book by its ID and creating brand new books. These map to the "Read one" and "Create" operations in CRUD.

In this step, get ready to:
  • Add a GET endpoint to fetch a single book by ID.
  • Add a POST endpoint to create new books.
  • Test both endpoints with curl commands.
Add GET /books/:id to fetch a single book

Right now, GET /books returns every book at once. Often you need just one specific book. Express lets you define route parameters (like :id) that capture a value directly from the URL.

  • In server.js, find the closing }); of your GET /books route.
  • Copy this code below it, before the // Start the server comment:
// GET /books/:id - Get a single book
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?

  • req.params.id grabs the value from the URL. If someone requests /books/2, the value is "2".
  • parseInt() converts it from a string to a number so it matches the numeric IDs in your books array.
  • books.find() searches the array for a book with a matching ID.
  • If no book is found, the server responds with a 404 status and a JSON error message. The return keyword stops the function so res.json(book) doesn't also run.
  • Save server.js.

You won't see a change yet. You'll restart the server and test this route after adding the POST endpoint.

Seeing a syntax error when you restart later?

  • Make sure this route is placed after the closing }); of your GET /books route, not inside it.
  • Check that you have matching opening and closing parentheses and braces for the app.get( call.

Help me fix a syntax error in my Express route

Add POST /books to create a new book

Reading data is only half the story. Your API also needs to accept new data from clients. A POST request sends data in the request body, and your server reads it, processes it, and sends back a confirmation.

  • In server.js, find the closing }); of the GET /books/:id route you just added.
  • Copy this code below it, before the // Start the server comment:
// POST /books - Create 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?

  • const { title, author } = req.body pulls the title and author fields out of the JSON the client sends.
  • The if (!title || !author) check returns a 400 (Bad Request) error if either field is missing. This is input validation.
  • nextId++ assigns the current value of nextId as the new book's ID, then increments it for the next book.
  • res.status(201).json(newBook) sends back the newly created book with a 201 status code, which means "Created".
  • Save server.js.

You won't see a change yet. The next substep restarts the server so you can test both new routes.

POST route not working when you test later?

  • Make sure app.use(express.json()) is still near the top of your file. This middleware is what lets Express read JSON from request bodies.
  • Check that you wrote app.post, not app.get. The HTTP method matters.

Help me debug my POST route in Express

Test both endpoints with curl

Both routes are in place. Time to restart your server and confirm everything works.

  • 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 Book API server running at http://localhost:3000 printed again.

  • Open a second terminal window to run your test commands.
  • Test fetching a single book by running:
curl http://localhost:3000/books/1

You should see the first book returned as JSON:

{"id":1,"title":"1984","author":"George Orwell"}
  • Test creating a new book by running:
curl -X POST http://localhost:3000/books -H "Content-Type: application/json" -d "{\"title\": \"Dune\", \"author\": \"Frank Herbert\"}"

You should see your new book returned with a 201 status and an auto-assigned ID of 4:

{"id":4,"title":"Dune","author":"Frank Herbert"}

Why does curl need all those flags?

The -X POST flag tells curl to use the POST method instead of the default GET. The -H flag sets a header telling the server to expect JSON. The -d flag carries the actual data (your new book's title and author).

Not getting the expected output?

  • If you see Cannot GET /books/1, make sure you saved server.js and restarted the server with Ctrl+C then node server.js.
  • If POST returns {} or undefined values, double-check that app.use(express.json()) appears before your routes.
  • On Windows, if curl gives a parsing error, make sure you're using escaped double quotes \" inside the -d string.

Help me troubleshoot my curl commands for testing my Express API

✔️ Awesome, I've got everything!

Great. Double check you've saved server.js and both curl commands returned the expected JSON.

ⓧ I'd like to double check the full code

Here's what your complete server.js should look like at this point:

const express = require('express');
const app = express();
const PORT = 3000;

// Middleware to parse JSON request bodies
app.use(express.json());

// Sample data - our "database" of books
let books = [
  { id: 1, title: '1984', author: 'George Orwell' },
  { id: 2, title: 'To Kill a Mockingbird', author: 'Harper Lee' },
  { id: 3, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' }
];

let nextId = 4;

// GET /books - Get all books
app.get('/books', (req, res) => {
  res.json(books);
});

// GET /books/:id - Get a single book
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 /books - Create 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(`Book API server running at http://localhost:${PORT}`);
});

Your API can now read individual books and create new ones. Next up, you'll add the ability to update and delete books to complete the full set of CRUD operations.

Add Update and Delete Endpoints

In the last step, you built endpoints to read a single book and create new books. Your API can now retrieve data and add to it.

A complete API also needs the ability to modify existing data and remove data entirely. In this step, you'll add PUT (update) and DELETE endpoints to finish your CRUD operations.

In this step, get ready to:
  • Add a PUT endpoint to update book details.
  • Add a DELETE endpoint to remove a book.
  • Test both endpoints with curl to confirm they work.
Add PUT /books/:id to update a book

The PUT method tells the server to replace or update an existing resource. Your PUT route will find a book by its ID, update the fields the client sends, and return the modified book.

  • In server.js, find the closing }); of your POST /books route.
  • Add the following PUT route below it:
// PUT /books/:id - Update a book
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?

This route handles PUT requests to /books/:id. It finds the book that matches the ID in the URL, just like your GET route does.

The key difference is what happens next. It reads title and author from the request body, then only updates the fields that were actually sent. This means you can update just the title, just the author, or both at once.

  • Save server.js.
Add DELETE /books/:id to remove a book

The DELETE method removes a resource from the server entirely. Your DELETE route uses a slightly different approach to find the book. Instead of getting the book object, it finds the book's position (index) in the array so it can remove it.

  • In server.js, add the following DELETE route below the PUT route you just added:
// DELETE /books/:id - Delete a book
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).send();
});

What does this code do?

This route uses findIndex instead of find. While find returns the book object, findIndex returns the book's position number in the array. You need that position to remove it with splice.

When findIndex returns -1, it means no match was found. The 204 status code means "No Content" because after deleting, there's nothing to send back.

  • Save server.js.

✔️ Awesome, I've got everything!

Great. Make sure you've saved your file before moving on to testing.

ⓧ I'd like to double check the full code

Here's the complete server.js file at this point:

const express = require('express');
const app = express();
const PORT = 3000;

// Middleware to parse JSON request bodies
app.use(express.json());

// Sample data - our "database" of books
let books = [
  { id: 1, title: '1984', author: 'George Orwell' },
  { id: 2, title: 'To Kill a Mockingbird', author: 'Harper Lee' },
  { id: 3, title: 'The Great Gatsby', author: 'F. Scott Fitzgerald' }
];

let nextId = 4;

// GET /books - Get all books
app.get('/books', (req, res) => {
  res.json(books);
});

// GET /books/:id - Get a single book
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 /books - Create 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 /books/:id - Update a book
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 /books/:id - Delete a book
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).send();
});

// Start the server
app.listen(PORT, () => {
  console.log(`Book API server running at http://localhost:${PORT}`);
});
Test update and delete with curl

Time to confirm both new endpoints work. You'll restart the server, update a book, delete it, then verify the changes stuck.

  • Switch to the terminal where your server is running.
  • Press Ctrl+C to stop the server.
  • Restart it by running:
node server.js
  • Open a second terminal window.
  • Test updating a book by running this curl command:
curl -X PUT http://localhost:3000/books/1 -H "Content-Type: application/json" -d "{\"title\": \"Updated Title\", \"author\": \"Updated Author\"}"

You should see the updated book returned as JSON with the new title and author.

  • Test deleting a book by running:
curl -X DELETE http://localhost:3000/books/1

This command returns no body (204 No Content means the deletion succeeded silently).

  • Verify the book was actually deleted by fetching all books:
curl http://localhost:3000/books

You should see only 2 books remaining in the array. Book with id 1 is gone.

What are these HTTP status codes?

Each status code communicates a specific outcome to the client. 200 means the request succeeded (the default). 204 means success with no content to return.

Your API now uses four different status codes: 200 (OK), 201 (Created), 204 (No Content), and 404 (Not Found). Choosing the right code helps clients understand what happened without parsing the response body.

Seeing 'Cannot PUT' or 'Cannot DELETE'?

Make sure you restarted the server after saving your changes. Node.js doesn't pick up file changes automatically.

Check that your route uses app.put and app.delete (not app.get or app.post). Also verify the route path is '/books/:id' with the colon before id.

Help me debug my PUT or DELETE route.

Your API now handles all four CRUD operations. You can create, read, update, and delete books. Next up, you'll tackle a secret mission to add search functionality.

Secret mission

Add a Search Endpoint

Your API can create, read, update, and delete books. But what if someone has hundreds of books and needs to find one by a specific author? Build a search endpoint that filters books by title or author using query parameters.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally, so there are no ongoing costs. Decide whether to keep your project files for future reference, pause the running server, or delete everything entirely.

Resources you used:

  • The book-api project folder on your Desktop (contains server.js, package.json, and node_modules/).
  • The running Node.js server process (if still active in your terminal).

Keep everything running

No action needed. Choose this if you're still actively building or want to continue experimenting with your API.

  • Your server keeps running as long as the terminal window stays open.
  • You can restart it any time by running node server.js from inside the book-api folder.
  • Node.js remains installed on your system for future projects.

Pause - I'll come back to this later

Stop the running server to free up the terminal, but keep your project files for later.

  • Switch to the terminal window where your server is running.
  • Press Ctrl+C to stop the server.
  • Your book-api folder stays on your Desktop. You can restart the server any time by opening a terminal, navigating to the folder, and running node server.js.

Delete - I don't want to use this again

Remove all project files and start fresh. This permanently deletes your code.

  • 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.

On macOS or Linux:

rm -rf ~/Desktop/book-api

On Windows (PowerShell):

Remove-Item -Recurse -Force ~\Desktop\book-api
  • Confirm the folder is gone by checking your Desktop.

Nice Work!

Nice Work!

You just built a REST API server from scratch using Node.js and Express. Your server can handle real HTTP requests, process JSON data, and respond with proper status codes.

Here's what you learned:

  • Built a working Express server that listens for HTTP requests and responds with JSON data.
  • Created a complete set of CRUD endpoints using proper HTTP methods (GET, POST, PUT, DELETE) and status codes (200, 201, 204, 404).
  • Tested every endpoint using curl commands directly from the terminal.
  • Added a search endpoint with query parameter filtering for case-insensitive partial matching.

Ready to quiz yourself?