DEV Community

Cover image for REST API Explained: What It Is, How It Works, and What Not to Do
Nishant Gaurav
Nishant Gaurav

Posted on

REST API Explained: What It Is, How It Works, and What Not to Do

Every app you use today is talking to a server somewhere. When you open Instagram and your feed loads, when you search on Swiggy and restaurants appear, when you log into your bank and your balance shows up — all of that is an API at work. And in most cases, that API is a REST API.

If you've heard the term but never quite understood what it means or how to actually build one, this article covers all three: what REST is, how it works internally, and the mistakes almost every beginner makes.


What REST Actually Is

REST stands for Representational State Transfer. The name sounds academic, but the idea is simple: it's a set of rules for how two systems should talk to each other over the internet.

Think of a restaurant. You don't walk into the kitchen and cook your own food. You tell a waiter what you want, the waiter takes your order to the kitchen, and the kitchen sends back what you asked for. The waiter is the API. REST is the set of rules that defines how that conversation happens: what language you speak, how you place the order, and what format the food comes back in.

In technical terms: your app (the client) sends a request to a server, the server processes it and sends back a response. REST defines the structure of both.


How REST Works: The Two Things That Matter

Every REST API call has two components: a URL and a method.

The URL tells the server where to look. It's the address of the resource you want. The method tells the server what to do with it. There are four methods you'll use for almost everything:

Method What it does Real-world equivalent
GET Fetch data Reading a menu
POST Create something new Placing an order
PUT Update existing data Changing your order
DELETE Remove something Cancelling your order

Here's what a real REST request looks like when you search for biryani on a food app:

GET https://api.foodapp.com/v1/restaurants?search=biryani
Authorization: Bearer your_token_here
Content-Type: application/json
Enter fullscreen mode Exit fullscreen mode

Three parts to notice here. The URL tells the server which resource you want (/restaurants) and what you're searching for (?search=biryani). The Authorization header tells the server who you are. The Content-Type header tells the server what format you're sending data in.

The server verifies your identity, queries its database, and sends back a response in JSON:

{
  "status": 200,
  "data": [
    { "name": "Biryani House", "rating": 4.5, "distance": "1.2 km" },
    { "name": "Royal Biryani", "rating": 4.2, "distance": "2.0 km" }
  ]
}
Enter fullscreen mode Exit fullscreen mode

The 200 status code means everything worked. REST uses standard HTTP status codes to communicate what happened: 200 for success, 201 for something newly created, 400 for a bad request from the client, 401 for unauthorized, 404 for not found, and 500 for a server error.


Building Your First REST API

The fastest way to understand REST is to build something minimal. Here's a simple REST API in Python using Flask that handles a list of books:

from flask import Flask, jsonify, request

app = Flask(__name__)

# In-memory data store (use a real database in production)
books = [
    {"id": 1, "title": "Clean Code", "author": "Robert Martin"},
    {"id": 2, "title": "The Pragmatic Programmer", "author": "Hunt & Thomas"}
]

# GET — fetch all books
@app.route("/books", methods=["GET"])
def get_books():
    return jsonify(books), 200

# GET — fetch one book by ID
@app.route("/books/<int:book_id>", methods=["GET"])
def get_book(book_id):
    book = next((b for b in books if b["id"] == book_id), None)
    if not book:
        return jsonify({"error": "Book not found"}), 404
    return jsonify(book), 200

# POST — add a new book
@app.route("/books", methods=["POST"])
def add_book():
    data = request.get_json()
    new_book = {"id": len(books) + 1, "title": data["title"], "author": data["author"]}
    books.append(new_book)
    return jsonify(new_book), 201   # 201 = Created

# DELETE — remove a book
@app.route("/books/<int:book_id>", methods=["DELETE"])
def delete_book(book_id):
    global books
    books = [b for b in books if b["id"] != book_id]
    return jsonify({"message": "Deleted"}), 200

if __name__ == "__main__":
    app.run(debug=True)
Enter fullscreen mode Exit fullscreen mode

Four endpoints, four HTTP methods, clean separation between what each route does. This is the core pattern every REST API follows regardless of the language or framework.


What Beginners Get Wrong

Using the wrong HTTP method. The most common mistake is using GET for everything, including creating or deleting data. Methods have semantic meaning. GET should never change server state. If your "fetch user" endpoint is also deleting something, that's broken by design.

Returning the wrong status codes. Returning 200 OK when something fails, or 500 for a validation error that was clearly the client's fault, confuses every developer who integrates with your API. Return 400 when the client sent bad data, 404 when a resource doesn't exist, and 500 only when your server genuinely broke.

Poor URL structure. URLs should represent resources, not actions. This is wrong:

POST /createUser
GET /getBooks
DELETE /removeBook?id=5
Enter fullscreen mode Exit fullscreen mode

This is correct:

POST /users
GET /books
DELETE /books/5
Enter fullscreen mode Exit fullscreen mode

The method already describes the action. The URL should only describe the resource.

No versioning. If you build an API and people start using it, you can't change the structure without breaking their code. Always version your API from the start: /v1/books. When you make breaking changes, release /v2/books and give consumers time to migrate.

Storing sensitive data without authentication. Every endpoint that returns private data needs to verify who's asking. Add token-based authentication (Authorization: Bearer <token>) before any route that touches user-specific information.


When REST Is Not the Right Choice

REST works well for most standard web applications. It starts showing limits when you need real-time data (a chat app where the server pushes new messages without being asked), highly flexible data fetching (a mobile app that needs different data shapes than the web version), or extremely high-frequency internal service calls where JSON parsing overhead adds up.

For those cases, WebSockets, GraphQL, and gRPC exist respectively. But for your first API and the majority of web projects, REST covers everything you need.


What You Now Understand

A REST API is a structured contract between a client and a server: a URL identifies the resource, an HTTP method describes the action, headers carry authentication and format metadata, and the response comes back as JSON with a status code that tells you what happened.

Build the book API above locally. Add a PUT endpoint that updates a book's title. Then deliberately break it: return a 200 for a request with missing fields and see how that makes the caller's job harder. The mistakes become obvious fastest when you make them yourself.

Top comments (0)