BackendAPI

REST API Tutorial: Build & Test APIs Like a Pro

TT
TopicTrick
REST API Tutorial: Build & Test APIs Like a Pro

REST API Tutorial: Build & Test APIs Like a Pro

REST (Representational State Transfer) APIs are the backbone of modern web applications. Every time you fetch a weather forecast, load tweets, or process a payment, you're almost certainly consuming a REST API.

Understanding how to build, design, and test REST APIs is one of the most valuable skills a developer can have.

What is a REST API? (Quick Answer)

A REST API is a web service that uses standard HTTP methods (GET, POST, PUT, DELETE) to perform operations on resources identified by URLs. It is stateless — each request carries all the information needed, and the server stores no session state between calls. This design makes REST APIs scalable, predictable, and easy to consume from any client.


What is a REST API?

Think of a REST API as a standard way for your phone or browser to "talk" to a server. For a solid conceptual foundation before diving in, see our guide on application programming interfaces (APIs). Before REST, every system had its own unique way of speaking. REST introduced a set of rules that made it so every computer could understand the same basic commands, like "give me this data" or "save this new user."

A true REST API follows these core principles:

  1. Client-Server: Separation of the user interface (client) from data storage (server).
  2. Stateless: Each request contains all the necessary information; the server doesn't remember previous requests.
  3. Cacheable: Responses should indicate if they can be cached to save bandwidth.
  4. Uniform Interface: Consistent resource naming (URLs) and HTTP methods.

Real-World Analogy

A REST API is like a restaurant menu. You (the client) choose items by name (the URL), tell the waiter what to do (the HTTP method), and the kitchen (the server) fulfills your request without knowing or caring who you are between requests.


    HTTP Methods & Status Codes

    When you use a REST API, you're usually doing one of four things: creating, reading, updating, or deleting data. We use specific "verbs" called HTTP methods to tell the server exactly which action we want to perform.

    Standard HTTP Methods (Verbs)

    MethodPurposeIs it Idempotent?
    GETRetrieve data (Read)Yes
    POSTCreate a new resourceNo
    PUTReplace a resource entirelyYes
    PATCHPartially update a resourceNo
    DELETERemove a resourceYes

    (Note: "Idempotent" means making the same request multiple times will have the same result as making it once. Deleting a user multiple times still just results in a deleted user).

    Common HTTP Status Codes

    The server uses Status Codes to tell us if our request worked or if something went wrong:

    • 200 OK: Standard response for successful GET, PUT, or PATCH requests.
    • 201 Created: A new resource has been successfully created (POST).
    • 400 Bad Request: The server cannot process the request due to client-side errors.
    • 401 Unauthorized: Authentication is required and failed.
    • 404 Not Found: The requested resource could not be found.
    • 500 Server Error: The server crashed or encountered an unexpected bug.

    REST API Design Principles

    Building an API is easy; building an API that other developers actually want to use is hard. Good design means your API is predictable.

    URL Structure Best Practices

    Always use resource-based, lowercase nouns in the plural form. Do not use verbs in the URL.

    text

    Consistent JSON Responses

    Always return a consistent JSON structure so clients know exactly what to expect.

    json

    Building a REST API with Node.js

    Let's build a real REST API endpoint using Express.js:

    javascript

    Authentication & Security

    You wouldn't want just anyone to be able to delete users from your database. Authentication verifies who is making the request. The global standard for API auth is the JSON Web Token (JWT).

    Client applications attach the token to the HTTP headers of their requests:

    text

    Security Best Practice

    Never store sensitive environment variables or JWT Secret Keys in your source code repository. Always use a `.env` file that is ignored by Git.


      API Testing & Debugging

      Testing APIs without a tool is painful. You can use command-line tools like curl or desktop apps like Postman to hit endpoints and view the formatted JSON responses.

      bash

      API Rate Limiting and Error Handling Best Practices

      Two areas that separate amateur APIs from production-grade ones are rate limiting and consistent error handling.

      Rate Limiting

      Rate limiting protects your server from abuse and ensures fair usage. Return a 429 Too Many Requests status code when a client exceeds the allowed number of requests. Always include a Retry-After header so the client knows when to try again.

      text

      Consistent Error Handling

      Never expose raw server errors or stack traces to API consumers. Always return structured, machine-readable error objects:

      json

      For deeper reading on protecting your APIs from malicious traffic, see our guide on how to protect APIs from attacks.


      REST API Security Checklist

      Before deploying any REST API to production, run through this checklist:

      • Use HTTPS for all endpoints — never serve API traffic over plain HTTP.
      • Validate and sanitize all input — use regex patterns to reject malformed data (see our regex tutorial).
      • Implement authentication on all non-public routes.
      • Set appropriate CORS headers to restrict which origins can call your API.
      • Log all requests, especially auth failures, for audit purposes.
      • Use parameterized queries to prevent SQL injection (see our SQL query examples).

      External resources worth bookmarking:


      Frequently Asked Questions

      What's the difference between REST and GraphQL?

      REST uses multiple endpoints (one per resource). GraphQL uses a single endpoint where clients specify exactly what data fields they need. REST is simpler and better for caching. GraphQL is more flexible for complex data fetching.

      How do I handle API versioning?

      Use URL versioning (/api/v1/, /api/v2/). Maintain older versions for at least 6-12 months with deprecation warnings to give developers time to migrate.

      Should my API use cookie-based or token-based auth?

      For APIs consumed by mobile apps or third parties, JWT (token-based) auth is preferred because it is stateless and cross-domain. For browser-only apps, secure HTTP-only cookies are generally safer from cross-site scripting (XSS).

      Common REST API Design Mistakes

      1. Using verbs in resource URLs REST resource URLs should identify nouns, not actions. /getTasks and /createTask break the REST convention. Use /tasks with the appropriate HTTP method: GET /tasks to list, POST /tasks to create, DELETE /tasks/{id} to remove. The HTTP verb carries the action; the URL identifies the resource. The IETF HTTP semantics RFC 9110 defines the meaning of each method.

      2. Returning 200 OK for all responses including errors Returning {"status": "error", "message": "not found"} with a 200 OK status code forces clients to parse the body to determine success or failure. Use the correct HTTP status codes: 400 for bad input, 401 for unauthenticated, 403 for unauthorized, 404 for not found, 422 for validation errors, 500 for server errors. Clients, load balancers, and monitoring tools rely on status codes. See the MDN HTTP status code reference.

      3. Not versioning the API Changing the structure of a response without versioning breaks all existing integrations immediately. Add a version prefix from day one: /api/v1/tasks. When a breaking change is needed, deploy /api/v2/tasks alongside v1 with a sunset date. RESTful API versioning strategies covers URL versioning, header versioning, and content negotiation.

      4. Exposing database IDs directly Using auto-increment integer IDs (/tasks/1, /tasks/2) allows clients to enumerate all resources sequentially. Use UUIDs or opaque identifiers instead. More importantly, always enforce authorisation — verify the requesting user is permitted to access the specific resource, not just that the ID exists.

      5. Ignoring pagination on list endpoints GET /tasks that returns all records in the database will eventually time out and exhaust memory. Implement pagination from the beginning using ?limit=20&offset=0 or cursor-based pagination. Return pagination metadata in the response: {"data": [...], "total": 500, "next_cursor": "abc123"}. The GitHub API pagination documentation is a good real-world example.

      Frequently Asked Questions

      What is the difference between REST and GraphQL? REST is an architectural style where each resource has its own URL and clients use standard HTTP methods to interact with it. GraphQL is a query language where clients send a single POST request describing exactly the data they need, and the server returns only that data. REST is simpler to cache, easier to debug, and universally supported. GraphQL reduces over-fetching and under-fetching and suits complex, relationship-heavy data models. The GraphQL official documentation explains the trade-offs. For most APIs, REST is the appropriate starting point.

      What HTTP status code should I return when a resource is not found? Return 404 Not Found when a resource with the requested identifier does not exist. If the resource exists but the user is not permitted to know it exists (security-sensitive cases), return 404 rather than 403 — leaking the existence of a resource can be a security issue. If the user is simply not authenticated, return 401 Unauthorized to prompt a login flow. The HTTP status code semantics in RFC 9110 defines 404 precisely.

      Should I use PUT or PATCH for updates? PUT replaces the entire resource with the supplied representation — omitting a field removes it. PATCH applies a partial update — only the supplied fields are changed. For most update operations, PATCH is more appropriate because clients rarely want to replace an entire resource. Use PUT only when the client controls the complete state of the resource (e.g., file upload to a known URI). The RFC 5789 PATCH method specification defines the semantics formally.