Node.js 및 Express로 처음부터 REST API를 구축하는 방법

작성자

카테고리:

← 피드로
DEV Community · Eugene Okogun · 2026-06-15 개발(SW)

Have you ever wondered how mobile apps and websites get their data? The answer is usually an API. In this tutorial, you will build a working REST API from scratch using Node.js and Express. By the end, you will have an API that can create, read, update, and delete data — the four core operations of any real-world application.

No prior API experience needed. If you know basic JavaScript, you are ready.

What You Will Build

A simple Books API that lets you:

  • Get a list of all books
  • Get a single book by ID
  • Add a new book
  • Update a book
  • Delete a book

Prerequisites

Before starting, make sure you have:

  • Node.js installed (version 14 or higher)
  • A code editor (VS Code recommended)
  • A terminal / command prompt
  • Postman or Thunder Client to test your API

Step 1: Set Up Your Project

Open your terminal and run these commands one by one:


# Create a new folder for your project
mkdir books-api

# Move into the folder
cd books-api

# Create a package.json file (just press Enter for all questions)
npm init -y

# Install Express
npm install express

Enter fullscreen mode Exit fullscreen mode

Now create a file called index.js inside your books-api folder. This is where all your code will live.

Your folder structure should look like this:

books-api/
  index.js
  package.json
  node_modules/

Enter fullscreen mode Exit fullscreen mode

Step 2: Create Your First Server

Open index.js and add this code:

// Import Express
const express = require('express');

// Create an Express app
const app = express();

// This line lets our API understand JSON data
app.use(express.json());

// Choose a port number for our server
const PORT = 3000;

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

Enter fullscreen mode Exit fullscreen mode

What each line does:

  • require('express') — loads the Express library we installed
  • app.use(express.json()) — tells Express to read JSON from incoming requests
  • app.listen(PORT) — starts the server and listens for requests on port 3000

Run your server:

node index.js

Enter fullscreen mode Exit fullscreen mode

You should see:

Server is running on http://localhost:3000

Enter fullscreen mode Exit fullscreen mode

Your server is live. Now let’s add data and routes.

Step 3: Add Some Sample Data

Since we are not using a database in this tutorial, we will store our books in an array. Add this to your index.js file, just below app.use(express.json()):

// Our "database" — a simple array of books
let books = [
  { id: 1, title: 'The Pragmatic Programmer', author: 'Andrew Hunt' },
  { id: 2, title: 'Clean Code', author: 'Robert C. Martin' },
  { id: 3, title: 'You Don't Know JS', author: 'Kyle Simpson' },
];

Enter fullscreen mode Exit fullscreen mode

Think of this array as a temporary database. Every time the server restarts, data resets — but it is perfect for learning.

Step 4: GET All Books

This route returns every book in our list. Add this below your books array:

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

Enter fullscreen mode Exit fullscreen mode

What is happening here:

  • app.get — we are setting up a GET route
  • '/books' — the URL path someone visits
  • req — the incoming request (what the user sends)
  • res — the response (what we send back)
  • res.json(books) — sends our books array as JSON

Test it: Open Postman, set the method to GET, and visit http://localhost:3000/books. You will see all three books.

Step 5: GET a Single Book

What if someone wants just one book? We use a URL parameter:

// GET /books/:id — returns one book by ID
app.get('/books/:id', (req, res) => {
  // Convert the id from text to a number
  const id = parseInt(req.params.id);

  // Find the book with that ID
  const book = books.find((b) => b.id === id);

  // If no book found, send a 404 error
  if (!book) {
    return res.status(404).json({ message: 'Book not found' });
  }

  // Send the book back
  res.json(book);
});

Enter fullscreen mode Exit fullscreen mode

What is happening here:

  • :id in the URL is a placeholder — it captures whatever number the user types
  • req.params.id reads that number from the URL
  • parseInt converts it from a string to a number
  • .find() searches the array for a matching book
  • If nothing is found, we return a 404 status with a helpful message

Test it: GET http://localhost:3000/books/1 returns the first book. GET http://localhost:3000/books/99 returns “Book not found”.

Step 6: POST — Add a New Book

Now let’s allow adding a new book:

// POST /books — adds a new book
app.post('/books', (req, res) => {
  // Get the title and author from the request body
  const { title, author } = req.body;

  // Simple validation — make sure both fields exist
  if (!title || !author) {
    return res.status(400).json({ message: 'Title and author are required' });
  }

  // Create the new book with a unique ID
  const newBook = {
    id: books.length + 1,
    title: title,
    author: author,
  };

  // Add it to our array
  books.push(newBook);

  // Send back the new book with a 201 status (means "created")
  res.status(201).json(newBook);
});

Enter fullscreen mode Exit fullscreen mode

Test it in Postman:

  • Method: POST
  • URL: http://localhost:3000/books
  • Body: raw → JSON
{
  "title": "Eloquent JavaScript",
  "author": "Marijn Haverbeke"
}

Enter fullscreen mode Exit fullscreen mode

You will get back the new book with an ID of 4.

Step 7: PUT — Update a Book

What if someone made a typo in a book title? This route fixes it:

// PUT /books/:id — updates an existing book
app.put('/books/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const { title, author } = req.body;

  // Find the position of the book in the array
  const index = books.findIndex((b) => b.id === id);

  // If book doesn't exist, return 404
  if (index === -1) {
    return res.status(404).json({ message: 'Book not found' });
  }

  // Update the book — keep the same ID, change title and author
  books[index] = { id, title, author };

  // Send back the updated book
  res.json(books[index]);
});

Enter fullscreen mode Exit fullscreen mode

Test it in Postman:

  • Method: PUT
  • URL: http://localhost:3000/books/1
  • Body:
{
  "title": "The Pragmatic Programmer (20th Anniversary Edition)",
  "author": "Andrew Hunt"
}

Enter fullscreen mode Exit fullscreen mode

Step 8: DELETE — Remove a Book

Finally, let’s allow deleting a book:

// DELETE /books/:id — removes a book
app.delete('/books/:id', (req, res) => {
  const id = parseInt(req.params.id);

  // Find the book's position in the array
  const index = books.findIndex((b) => b.id === id);

  // If not found, return 404
  if (index === -1) {
    return res.status(404).json({ message: 'Book not found' });
  }

  // Remove the book from the array
  books.splice(index, 1);

  // Confirm deletion
  res.json({ message: 'Book deleted successfully' });
});

Enter fullscreen mode Exit fullscreen mode

Test it: DELETE http://localhost:3000/books/2 removes Clean Code from the list. Do a GET on /books and confirm it is gone.

Your Complete index.js File

Here is the full code in one place:

const express = require('express');
const app = express();
app.use(express.json());

const PORT = 3000;

let books = [
  { id: 1, title: 'The Pragmatic Programmer', author: 'Andrew Hunt' },
  { id: 2, title: 'Clean Code', author: 'Robert C. Martin' },
  { id: 3, title: "You Don't Know JS", author: 'Kyle Simpson' },
];

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

// GET one 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({ message: '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({ message: 'Title and author are required' });
  const newBook = { id: books.length + 1, title, author };
  books.push(newBook);
  res.status(201).json(newBook);
});

// PUT update a book
app.put('/books/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const { title, author } = req.body;
  const index = books.findIndex((b) => b.id === id);
  if (index === -1) return res.status(404).json({ message: 'Book not found' });
  books[index] = { id, title, author };
  res.json(books[index]);
});

// 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({ message: 'Book not found' });
  books.splice(index, 1);
  res.json({ message: 'Book deleted successfully' });
});

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

Enter fullscreen mode Exit fullscreen mode

What You Just Built

You now have a fully working REST API with five routes:

Method Route What it does GET /books Returns all books GET /books/:id Returns one book POST /books Adds a new book PUT /books/:id Updates a book DELETE /books/:id Deletes a book

What to Learn Next

Now that your API works, here are natural next steps:

  • Add a real database — connect MongoDB or PostgreSQL instead of an array
  • Add authentication — protect your routes with JWT tokens
  • Deploy your API — put it online using Railway or Render (both free)
  • Add input validation — use a library like express-validator for stricter checks

Conclusion

Building a REST API with Node.js and Express is simpler than most people think. You started from an empty folder and ended up with a working API that handles all four CRUD operations. Every API you use daily — Twitter, Instagram, your banking app — works on these same principles at its core.

The code in this tutorial is intentionally simple so you can focus on understanding the concepts. Once these feel comfortable, adding a database and authentication becomes a natural next step.

Happy building.


Enter fullscreen mode Exit fullscreen mode

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다