How to build your first API with Node.js

How to Build Your First API with Node.js

How to build your first API with Node.js

An API (application programming interface) is a way for programs to talk to each other. When a website loads data or an app shows the weather, an API is often involved. Many APIs work over HTTP but return data, usually as JSON, instead of a web page. In this guide you will build a small books API with Node.js and Express, a popular beginner-friendly framework, and test it on your own computer.

What You Need Before You Start

You should have Node.js and npm installed. Check with:

node --version
npm --version

Both commands should print version numbers. You will also need a code editor. Visual Studio Code is a common choice, but any editor will do.

We will store books in memory, in a simple array, rather than a database, to keep the focus on the API. In a real app you would replace it with a database, but the routes would look very similar.

Setting Up the Project

Create a folder for the project and move into it:

mkdir books-api
cd books-api
npm init -y

The npm init -y command creates a package.json file with default settings. This file describes your project and lists its dependencies.

Next, install Express:

npm install express

Express is a minimal web framework that makes defining routes and handling requests easier than using the built-in http module directly.

Creating a Basic Server

Create a file called index.js and add this code:

const express = require("express");
const app = express();

app.use(express.json());

app.get("/", (req, res) => {
  res.json({ message: "Welcome to the Books API!" });
});

const PORT = 3000;
app.listen(PORT, () => {
  console.log(`Server running at http://localhost:${PORT}`);
});

The first lines load Express and create an app. app.use(express.json()) tells Express to parse JSON request bodies. The app.get line defines a route: a GET request to / returns a JSON message. Finally, app.listen starts the server on port 3000. Run it with:

node index.js

Then open http://localhost:3000 in your browser to see the welcome message as JSON. Keep the server running while testing, restarting after each change (or use nodemon to restart automatically).

Understanding Routes and HTTP Methods

A route has a path (e.g. /books) and an HTTP method: GET retrieves, POST creates, PUT/PATCH updates, and DELETE removes — together called CRUD (create, read, update, delete). A REST API follows these conventions: GET /books lists all books, GET /books/1 returns one, POST /books adds one, and DELETE /books/1 removes one.

Adding a List of Books

Now add some data and a route to list it. Update index.js so it includes a books array above the routes:

let books = [
  { id: 1, title: "Eloquent JavaScript", author: "Marijn Haverbeke" },
  { id: 2, title: "Clean Code", author: "Robert Martin" },
  { id: 3, title: "You Don't Know JS", author: "Kyle Simpson" },
];

app.get("/books", (req, res) => {
  res.json(books);
});

Visit http://localhost:3000/books to see the full list. Next, add a route for a single book, where :id is a route parameter capturing part of the URL:

app.get("/books/:id", (req, res) => {
  const id = Number(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);
});

Note the status codes: 200 means success (the default) and 404 means not found. Returning the right code with a clear message helps clients handle problems. Try /books/99 to see the error.

Adding a Book with POST

To create data, clients send a POST request with a JSON body. Add this route:

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: books.length ? Math.max(...books.map((b) => b.id)) + 1 : 1,
    title,
    author,
  };

  books.push(newBook);
  res.status(201).json(newBook);
});

The 400 status means the request was invalid, and 201 means a resource was created. Validation matters: never trust a client to always send complete data. You cannot send POST from a browser address bar, so use curl from another terminal:

curl -X POST http://localhost:3000/books \
  -H "Content-Type: application/json" \
  -d '{"title": "Node.js Design Patterns", "author": "Mario Casciaro"}'

You should see the new book returned with a server-assigned id, and GET /books will now include it.

Updating and Deleting Books

Here are simple update and delete routes:

app.put("/books/:id", (req, res) => {
  const id = Number(req.params.id);
  const book = books.find((b) => b.id === id);

  if (!book) {
    return res.status(404).json({ error: "Book not found" });
  }

  book.title = req.body.title || book.title;
  book.author = req.body.author || book.author;
  res.json(book);
});

app.delete("/books/:id", (req, res) => {
  const id = Number(req.params.id);
  const before = books.length;
  books = books.filter((b) => b.id !== id);

  if (books.length === before) {
    return res.status(404).json({ error: "Book not found" });
  }

  res.json({ message: "Book deleted" });
});

Note that books uses let, not const, because delete reassigns it. In a real project these routes would update a database, with stronger validation and authentication.

Testing and Debugging

Test as you go: use the browser for GET requests and curl or Postman for POST, PUT, and DELETE. If something fails, read the terminal output — common problems are forgetting to restart the server, forgetting express.json() (so req.body is empty), and typos in route paths. Remember that in-memory data disappears on restart; adding a database is a natural next project.

What to Learn Next

Once it works, try extending it: search by title, list books by author, or validate input more strictly. Then learn about databases, asynchronous code, authentication, and fetching this API from a front-end page with fetch.

Conclusion

You have built a working API: listing, fetching, adding, updating, and deleting books — the core pattern behind most web APIs. Next, practise with new resources, add a database, and improve error handling. The first API is the hardest; every one after gets easier.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *