← All Articles Β· Β· 11 min read

How to Build a REST API in 10 Minutes: A Beginner's Guide

Learn how to build a REST API in 10 minutes with Node.js and Express. Step-by-step tutorial with code examples, testing tips, and best practices for beginners.

rest-apinodejsexpressbackendapi-developmentbeginner

How to Build a REST API in 10 Minutes: A Beginner’s Guide

If you’ve been wondering how to build a REST API but don’t know where to start, you’re in the right place. In this tutorial, you’ll go from zero to a fully working REST API in about 10 minutes β€” no prior backend experience required. We’ll use Node.js and Express, two of the most beginner-friendly tools for backend development, and walk through every step with complete working code.

By the end, you’ll have a real API running on your machine that you can test, extend, and build on.


What Is a REST API?

Before we write any code, let’s make sure you understand what a REST API actually is β€” because the terminology can feel intimidating at first.

REST stands for Representational State Transfer. It’s an architectural style for designing web services. A REST API (or RESTful API) is a way for two applications to talk to each other over HTTP β€” the same protocol your browser uses to load websites.

Think of a REST API as a waiter at a restaurant:

  • You (the client) make a request β€” β€œI’d like the spaghetti carbonara.”
  • The kitchen (the server) processes your request and sends back a response β€” your plate of pasta.

In technical terms:

  • The client sends an HTTP request (GET, POST, PUT, DELETE) to a specific URL (called an endpoint).
  • The server processes the request and returns data, usually in JSON format.

The Four Core HTTP Methods

REST APIs are built around four primary HTTP methods that map to four basic operations (often called CRUD):

MethodOperationExample
GETReadFetch a list of users
POSTCreateAdd a new user
PUTUpdateUpdate an existing user
DELETEDeleteRemove a user

Understanding these four methods is 80% of understanding REST APIs. Now let’s build one.


Prerequisites

To follow this tutorial, you need:

  1. Node.js installed β€” Download from nodejs.org. Install the LTS version.
  2. npm β€” It comes bundled with Node.js automatically.
  3. A code editor β€” VS Code is recommended.
  4. A terminal β€” Terminal on Mac/Linux, Command Prompt or PowerShell on Windows.

That’s it. No database setup, no cloud accounts, no complex configuration. We’ll keep everything simple and local.

To verify Node.js is installed, run:

node --version
npm --version

You should see version numbers printed. If you do, you’re ready to go.


Step 1: Set Up Your Project

Open your terminal and run the following commands to create a new project folder and initialize it:

mkdir my-rest-api
cd my-rest-api
npm init -y

The npm init -y command creates a package.json file with default settings. This file tracks your project’s dependencies and configuration.

Next, install Express β€” the lightweight web framework we’ll use to build our API:

npm install express

You’ll also want to install nodemon, a development tool that automatically restarts your server whenever you save a file:

npm install --save-dev nodemon

Now open your package.json file and add a start script under the scripts section:

{
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js"
  }
}

Your project structure should now look like this:

my-rest-api/
β”œβ”€β”€ node_modules/
β”œβ”€β”€ package.json
└── package-lock.json

Step 2: Create Your First Express Server

Create a new file called index.js in your project root and add the following code:

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

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

// Root route β€” just to confirm the server is running
app.get('/', (req, res) => {
  res.json({ message: 'Welcome to my REST API!' });
});

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

Now start the development server:

npm run dev

Open your browser and navigate to http://localhost:3000. You should see:

{ "message": "Welcome to my REST API!" }

Congratulations β€” you have a running server. Now let’s turn it into a real REST API.


Step 3: Build a Full CRUD REST API

We’ll build a simple Books API that lets you create, read, update, and delete books. In a production app, this data would come from a database β€” but for this tutorial, we’ll store everything in memory (an array).

Replace the contents of index.js with the following complete implementation:

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

app.use(express.json());

// In-memory "database"
let books = [
  { id: 1, title: 'The Pragmatic Programmer', author: 'Andrew Hunt', year: 1999 },
  { id: 2, title: 'Clean Code', author: 'Robert C. Martin', year: 2008 },
  { id: 3, title: 'You Don\'t Know JS', author: 'Kyle Simpson', year: 2015 },
];

let nextId = 4;

// ─────────────────────────────────────────
// GET /books β€” Retrieve all books
// ─────────────────────────────────────────
app.get('/books', (req, res) => {
  res.json(books);
});

// ─────────────────────────────────────────
// GET /books/:id β€” Retrieve 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, year } = req.body;

  if (!title || !author || !year) {
    return res.status(400).json({ error: 'title, author, and year are required' });
  }

  const newBook = { id: nextId++, title, author, year };
  books.push(newBook);

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

// ─────────────────────────────────────────
// PUT /books/:id β€” Update an existing book
// ─────────────────────────────────────────
app.put('/books/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const bookIndex = books.findIndex(b => b.id === id);

  if (bookIndex === -1) {
    return res.status(404).json({ error: 'Book not found' });
  }

  const { title, author, year } = req.body;
  books[bookIndex] = { id, title, author, year };

  res.json(books[bookIndex]);
});

// ─────────────────────────────────────────
// DELETE /books/:id β€” Delete a book
// ─────────────────────────────────────────
app.delete('/books/:id', (req, res) => {
  const id = parseInt(req.params.id);
  const bookIndex = books.findIndex(b => b.id === id);

  if (bookIndex === -1) {
    return res.status(404).json({ error: 'Book not found' });
  }

  books.splice(bookIndex, 1);
  res.status(204).send();
});

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

Save the file. Nodemon will automatically restart the server.

What This Code Does

Let’s walk through each endpoint:

  • GET /books β€” Returns the full list of books as a JSON array.
  • GET /books/:id β€” Returns a single book by its ID. Returns a 404 error if not found.
  • POST /books β€” Accepts a JSON body with title, author, and year. Validates the input, creates a new book, and returns it with a 201 Created status.
  • PUT /books/:id β€” Replaces a book’s data entirely. Returns 404 if the book doesn’t exist.
  • DELETE /books/:id β€” Removes a book from the list and returns 204 No Content.

Notice that we’re using proper HTTP status codes throughout. This is an important REST API convention. Not sure what a specific status code means? Check out the HTTP Status Codes reference β€” it covers every code with plain-English explanations.


Step 4: Test Your REST API

Now that your API is running, you need to test it. You have a few options.

Option 1: Use curl (Command Line)

If you’re comfortable with the terminal, curl is the fastest way to test endpoints:

# Get all books
curl http://localhost:3000/books

# Get a single book
curl http://localhost:3000/books/1

# Create a new book
curl -X POST http://localhost:3000/books \
  -H "Content-Type: application/json" \
  -d '{"title": "JavaScript: The Good Parts", "author": "Douglas Crockford", "year": 2008}'

# Update a book
curl -X PUT http://localhost:3000/books/1 \
  -H "Content-Type: application/json" \
  -d '{"title": "The Pragmatic Programmer", "author": "Andrew Hunt & David Thomas", "year": 2019}'

# Delete a book
curl -X DELETE http://localhost:3000/books/2

Option 2: Use the API Request Builder

If you prefer a visual interface, use the API Request Builder to test your API endpoints directly in the browser. It lets you configure HTTP methods, set headers, and write request bodies without touching the terminal β€” perfect for beginners learning how to build a REST API.

Option 3: Use Postman or Insomnia

For a more full-featured testing experience, tools like Postman and Insomnia let you save your requests, organize them into collections, and share them with teammates.

Expected Responses

Here’s what you should see when you test each endpoint:

GET /books β€” returns an array:

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

POST /books with a new book β€” returns the created object with status 201:

{
  "id": 4,
  "title": "JavaScript: The Good Parts",
  "author": "Douglas Crockford",
  "year": 2008
}

GET /books/99 (non-existent) β€” returns status 404:

{ "error": "Book not found" }

When you’re comparing API responses across different test runs, the JSON Diff Viewer is incredibly handy for spotting exactly what changed between two response bodies.


Step 5: Add Error Handling Middleware

A production-quality REST API needs a centralized error handler. Without one, unhandled errors will crash your server or leak stack traces to users.

Add this at the bottom of your index.js, just before app.listen:

// 404 handler for unknown routes
app.use((req, res) => {
  res.status(404).json({ error: `Route ${req.method} ${req.path} not found` });
});

// Global error handler
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).json({ error: 'Something went wrong. Please try again.' });
});

The 404 handler catches any request that doesn’t match your defined routes. The global error handler catches any uncaught exceptions thrown inside your route handlers β€” just pass the error to next(err) from any route and this middleware will handle it.


REST API Best Practices for Beginners

Now that you know how to build a REST API, let’s cover the principles that separate a good API from a bad one. These habits will save you hours of debugging down the road.

1. Use Nouns for Resource Names, Not Verbs

Bad:

GET /getBooks
POST /createBook
DELETE /deleteBook/1

Good:

GET /books
POST /books
DELETE /books/1

The HTTP method already describes the action. Your URL should describe the resource, not the action.

2. Always Return Appropriate HTTP Status Codes

Status codes communicate intent. Don’t return 200 OK for errors, and don’t return 400 Bad Request when something is missing on the server side.

Common codes to know:

  • 200 OK β€” Successful GET or PUT
  • 201 Created β€” Resource successfully created via POST
  • 204 No Content β€” Successful DELETE (no body to return)
  • 400 Bad Request β€” Client sent invalid data
  • 401 Unauthorized β€” Authentication required
  • 403 Forbidden β€” Authenticated but not allowed
  • 404 Not Found β€” Resource doesn’t exist
  • 500 Internal Server Error β€” Something broke on the server

Refer to the HTTP Status Codes reference whenever you’re unsure which code to use.

3. Version Your API

As your API evolves, you’ll need to make breaking changes. Without versioning, you’ll break existing clients the moment you change a response shape. Add a version prefix from day one:

/v1/books
/v1/books/:id

That way, when you release v2, old clients can keep using /v1 while new clients use /v2.

4. Validate Input Early

Never trust data coming from the client. Always validate request bodies before processing them. In the example above, we checked for required fields manually. For larger projects, consider a validation library like Joi or Zod:

npm install joi
const Joi = require('joi');

const bookSchema = Joi.object({
  title: Joi.string().min(1).max(200).required(),
  author: Joi.string().min(1).max(100).required(),
  year: Joi.number().integer().min(1000).max(2100).required(),
});

app.post('/books', (req, res) => {
  const { error, value } = bookSchema.validate(req.body);
  if (error) {
    return res.status(400).json({ error: error.details[0].message });
  }
  // proceed with validated `value`
});

5. Use Consistent JSON Response Shapes

Clients are much easier to write when your API always returns predictable shapes. Consider wrapping all responses in a consistent envelope:

{
  "success": true,
  "data": { ... },
  "error": null
}

Or for errors:

{
  "success": false,
  "data": null,
  "error": "Book not found"
}

Pick a shape and stick to it across your entire API.

6. Never Expose Sensitive Data

Never return passwords, API keys, or internal IDs in API responses. Even in development, build the habit of explicitly selecting which fields to return:

// Bad β€” returning everything from the database record
res.json(userFromDatabase);

// Good β€” explicitly selecting safe fields
const { id, name, email } = userFromDatabase;
res.json({ id, name, email });

Where to Go From Here

You now know how to build a REST API from scratch using Node.js and Express. The foundation you’ve built β€” routes, HTTP methods, status codes, JSON responses, and input validation β€” applies to every REST API you’ll ever build, regardless of language or framework.

Here are natural next steps to level up:

  • Connect a real database β€” Try SQLite (easiest) or PostgreSQL with the pg library. Replace the in-memory array with actual database queries.
  • Add authentication β€” Learn JWT (JSON Web Tokens) for stateless authentication. The jsonwebtoken and bcrypt libraries make this straightforward.
  • Use environment variables β€” Never hardcode ports, database URLs, or secrets. Use the dotenv package to load config from a .env file.
  • Write automated tests β€” Learn Jest and Supertest to write tests that verify your API endpoints automatically.
  • Deploy your API β€” Try Railway, Render, or Fly.io for free hosting. All three support Node.js with minimal configuration.

Try It Free at DevPlaybook.cc

Building and testing REST APIs is much smoother with the right tools in your corner. At devplaybook.cc, you’ll find a free suite of developer tools built exactly for moments like this:

  • API Request Builder β€” Send HTTP requests to any endpoint directly from your browser. No setup required. Perfect for testing the API you just built.
  • HTTP Status Codes Reference β€” Look up any status code instantly with plain-English explanations and usage guidance.
  • JSON Diff Viewer β€” Paste two JSON objects side by side and immediately see every difference. Essential when debugging API responses.

All tools are free, run in your browser, and require no account. Whether you’re just learning how to build a REST API or you’re a senior engineer who needs a quick reference, DevPlaybook has you covered.

Try it free at devplaybook.cc β€” no sign-up needed.


Summary

Here’s what you accomplished in this tutorial:

  • Learned what a REST API is and how the HTTP method + endpoint pattern works
  • Set up a Node.js + Express project from scratch
  • Built a complete CRUD API with GET, POST, PUT, and DELETE endpoints
  • Added proper HTTP status codes and error handling
  • Tested the API using curl and browser tools
  • Learned six best practices that separate good APIs from bad ones

The same steps you followed here β€” create a server, define routes, handle requests, return JSON β€” are the foundation of every REST API in production today. Now go build something.

Free Newsletter

Level Up Your Dev Workflow

Get new tools, guides, and productivity tips delivered to your inbox.

Plus: grab the free Developer Productivity Checklist when you subscribe.

Found this guide useful? Check out our free developer tools.