---
term: 'REST API'
seoTitle: 'What is a REST API? Constraints, Methods, Status Codes'
headline: 'What is a REST API?'
slug: rest-api
category: api-realtime
shortDefinition: 'A REST API is an API that follows the REST architectural style: resources at URLs, stateless requests, and standard HTTP methods.'
relatedTerms:
  - api
  - graphql-vs-rest
  - auto-generated-database-apis
  - crud-operations
contrastsWith:
  - graphql-vs-rest
aboutTerms:
  - 'REST (Representational State Transfer)'
  - 'RESTful API'
faq:
  - question: 'What is a REST API in simple terms?'
    answer: 'A way for two applications to talk over HTTP using conventions everyone already knows: each thing (a user, an order) lives at a URL, you act on it with a standard verb — GET to read, POST to create, PUT or PATCH to update, DELETE to remove — and every request stands alone, carrying everything the server needs to answer it.'
  - question: 'What does REST stand for?'
    answer: 'Representational State Transfer, from Roy Fielding''s 2000 doctoral dissertation. The name describes the mechanism: the server transfers a representation of a resource''s state (usually JSON) to the client, and the client moves the application from state to state through those representations.'
  - question: 'What is the difference between REST and RESTful?'
    answer: 'In everyday usage, nothing — the terms are interchangeable. Pedantically, REST names the architectural style and RESTful is the adjective for an API implementing it. The circulating claim that "RESTful follows all the rules and REST only some" has no basis in Fielding''s work.'
  - question: 'What are the six REST constraints?'
    answer: 'Client-server separation, statelessness, cacheability, uniform interface, layered system, and — optionally — code on demand. The uniform interface itself unpacks into four rules: resources identified by URIs, manipulation through representations, self-descriptive messages, and hypermedia as the engine of application state.'
  - question: 'What is the difference between PUT and POST?'
    answer: 'Idempotency and addressing. POST creates under a collection — the server assigns the URL, and repeating the request creates duplicates. PUT writes a full representation to a known URL — repeating it yields the same state, which makes retries safe. That safety difference, not style, is why the distinction matters.'
  - question: 'Does a REST API have to use JSON?'
    answer: 'No. REST is format-agnostic — a resource can be represented as JSON, XML, HTML, or an image, negotiated through the Accept and Content-Type headers. JSON is simply the modern default because every client parses it cheaply. The constraint is about representations, not about any particular one.'
  - question: 'What does stateless mean in a REST API?'
    answer: 'The server keeps no memory of the client between requests: each request carries everything needed to process it, including credentials such as a bearer token. The payoff is horizontal scale — any server can answer any request — and the cost is a few repeated bytes of context per call.'
  - question: 'What is HATEOAS?'
    answer: 'Hypermedia As The Engine Of Application State: responses include links to the actions available next, so clients navigate the API the way people navigate the web — by following links rather than hardcoding URLs. It is the least-implemented constraint; most production "REST" APIs skip it and live happily at level 2 of the maturity model.'
codeLanguages: [javascript, dart, swift, kotlin]
externalAuthorities:
  - name: 'Fielding dissertation, Chapter 5 — Representational State Transfer'
    url: 'https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm'
  - name: 'RFC 9110 — HTTP Semantics'
    url: 'https://www.rfc-editor.org/rfc/rfc9110'
  - name: 'HTTP request methods — MDN Web Docs'
    url: 'https://developer.mozilla.org/en-US/docs/Web/HTTP/Reference/Methods'
  - name: 'Richardson Maturity Model — Martin Fowler'
    url: 'https://martinfowler.com/articles/richardsonMaturityModel.html'
cta:
  title: 'A REST API you don''t have to build'
  text: 'Every Back4app data model ships as a REST API automatically — resource URLs, proper methods and status codes, auth and permissions at the boundary — plus SDKs that wrap it idiomatically on every platform.'
  linkText: 'Start building free'
  linkUrl: 'https://www.back4app.com/signup'
author: 'Back4app Engineering'
publishedDate: '2026-07-24'
translationKey: rest-api
---

**A REST API is an API that follows the REST architectural style: resources at URLs, stateless requests, and standard HTTP methods.** REST — Representational State Transfer, defined in Roy Fielding's 2000 [dissertation](https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm) — is a style, not a protocol or standard: a set of constraints that, honored together, produce APIs the whole web already knows how to consume, cache, and scale.

## Key takeaways

| Question | Answer |
| --- | --- |
| The model | Resources at URLs · representations (usually JSON) · standard methods |
| The source | Fielding's 2000 dissertation, chapter 5 — an architectural style, not a spec |
| The six constraints | Client-server · stateless · cacheable · uniform interface · layered · code on demand (optional) |
| The verbs | GET · POST · PUT · PATCH · DELETE — with safety and idempotency semantics |
| The honest footnote | Most production "REST" APIs are level-2 HTTP APIs — and that's fine |

## A full CRUD cycle in raw HTTP

The whole style in four requests — this is what every framework and SDK ultimately sends:

```text
POST /v1/posts                     →  201 Created            create
{ "title": "Hello REST" }             Location: /v1/posts/8fk2

GET /v1/posts/8fk2                 →  200 OK                 read
                                      { "title": "Hello REST", … }

PUT /v1/posts/8fk2                 →  200 OK                 replace
{ "title": "Hello again" }            (PATCH would update fields)

DELETE /v1/posts/8fk2              →  204 No Content         delete
GET /v1/posts/8fk2                 →  404 Not Found          …and it's gone
```

The same cycle through SDKs that wrap the REST calls:

**JavaScript:**

```javascript
// JavaScript / Node.js — Back4app JS SDK
// The REST semantics, wrapped: create, read, update, delete
const post = new Parse.Object('Post');
post.set('title', 'Hello REST');
await post.save();                            // POST   /classes/Post      → 201

const fetched = await new Parse.Query('Post')
  .get(post.id);                              // GET    /classes/Post/:id  → 200

fetched.set('title', 'Hello again');
await fetched.save();                         // PUT    /classes/Post/:id  → 200

await fetched.destroy();                      // DELETE /classes/Post/:id  → 200
```

**Flutter:**

```dart
// Flutter / Dart — Back4app Flutter SDK
// The REST semantics, wrapped: create, read, update, delete
final post = ParseObject('Post')..set('title', 'Hello REST');
await post.save();          // POST   /classes/Post      → 201

await post.fetch();         // GET    /classes/Post/:id  → 200

post.set('title', 'Hello again');
await post.save();          // PUT    /classes/Post/:id  → 200

await post.delete();        // DELETE /classes/Post/:id  → 200
```

**Swift:**

```swift
// iOS / Swift — Back4app Swift SDK
// The REST semantics, wrapped: create, read, update, delete
var post = Post()
post.title = "Hello REST"
let saved = try await post.save()      // POST   /classes/Post      → 201

let fetched = try await saved.fetch()  // GET    /classes/Post/:id  → 200

var updated = fetched
updated.title = "Hello again"
_ = try await updated.save()           // PUT    /classes/Post/:id  → 200

try await updated.delete()             // DELETE /classes/Post/:id  → 200
```

**Kotlin:**

```kotlin
// Android / Kotlin — Back4app Android SDK
// The REST semantics, wrapped: create, read, update, delete
val post = ParseObject("Post")
post.put("title", "Hello REST")
post.save()                                    // POST   /classes/Post      → 201

val fetched = ParseQuery.getQuery<ParseObject>("Post")
    .get(post.objectId)                        // GET    /classes/Post/:id  → 200

fetched.put("title", "Hello again")
fetched.save()                                 // PUT    /classes/Post/:id  → 200

fetched.delete()                               // DELETE /classes/Post/:id  → 200
```

## The six constraints of REST

1. **Client-server** — interface and implementation evolve independently; the UI never knows how storage works.
2. **Stateless** — every request is self-contained; the server holds no session between calls, which is what lets any replica answer any request.
3. **Cacheable** — responses declare their own cacheability; GETs with proper cache headers make the web's entire caching infrastructure (browsers, [CDNs](/glossary/cdn-content-delivery-network/), proxies) work for your API.
4. **Uniform interface** — the constraint that *is* REST, in four parts: resources identified by URIs; manipulation through representations (you send back the JSON you want the resource to become); self-descriptive messages (method + headers say everything needed to process the request); and hypermedia as the engine of application state (responses link to next actions).
5. **Layered system** — clients can't tell whether they're talking to the origin, a cache, or a gateway; intermediaries slot in freely.
6. **Code on demand** *(optional)* — servers may ship executable code to clients; the one constraint marked optional, and the one most APIs ignore.

## HTTP methods: safety, idempotency, CRUD

The table missing from nearly every ranking page — [RFC 9110's](https://www.rfc-editor.org/rfc/rfc9110) semantics, condensed:

| Method | CRUD role | Safe? | Idempotent? | Retry blindly? |
| --- | --- | --- | --- | --- |
| GET | Read | Yes | Yes | Yes |
| POST | Create | No | **No** | No — may duplicate |
| PUT | Replace | No | Yes | Yes — same result |
| PATCH | Partial update | No | Not guaranteed | Depends on patch design |
| DELETE | Remove | No | Yes | Yes — still gone |

*Safe* means the request changes nothing; *idempotent* means repeating it changes nothing further. These aren't trivia — they are the retry policy: a network timeout on PUT can be retried without fear, the same timeout on POST needs an idempotency key or a duplicate check. Full [CRUD mapping](/glossary/crud-operations/) has its own entry.

## Status codes: what to return when

| Situation | Return |
| --- | --- |
| Read succeeded | 200 OK |
| Created a resource | 201 Created + `Location` header |
| Deleted; nothing to say | 204 No Content |
| Malformed request | 400 Bad Request |
| No/invalid credentials | 401 Unauthorized |
| Authenticated but not allowed | 403 Forbidden |
| No such resource | 404 Not Found |
| Over the rate limit | 429 Too Many Requests ([details](/glossary/api-rate-limiting-throttling/)) |
| Server fault | 500 Internal Server Error |

The 401/403 and 200/201/204 distinctions are where API craftsmanship shows: precise codes make clients debuggable with nothing but the status line.

## Is your API really REST? The maturity ladder

The honest section commercial explainers omit. The [Richardson Maturity Model](https://martinfowler.com/articles/richardsonMaturityModel.html) grades HTTP APIs: level 0 (one URL, one verb, RPC in disguise), level 1 (resources at URLs), level 2 (proper methods and status codes), level 3 (hypermedia — HATEOAS).

```mermaid
flowchart TB
  accTitle: Richardson Maturity Model for REST APIs
  accDescr: Four levels from level zero, plain HTTP tunneling, through resources, then HTTP verbs and status codes, to level three hypermedia controls, with most production APIs sitting at level two.
  L0["Level 0 — one endpoint, POST everything (RPC in disguise)"] --> L1["Level 1 — resources: /posts/8fk2"]
  L1 --> L2["Level 2 — verbs + status codes ← most production APIs live here"]
  L2 --> L3["Level 3 — hypermedia: responses link the next actions (HATEOAS)"]
```

By Fielding's own insistence, an API without hypermedia isn't REST — he wrote a pointed essay saying exactly that. In practice, almost every acclaimed "REST API" is a level-2 HTTP API: resources, verbs, status codes, JSON, no hypermedia. This matters less as purity and more as vocabulary — knowing the ladder tells you what the term means in a job posting (level 2) versus the dissertation (level 3), and saves you from both cargo-cult HATEOAS and pedantic corrections.

## REST vs. SOAP vs. GraphQL vs. gRPC

| | REST | SOAP | GraphQL | gRPC |
| --- | --- | --- | --- | --- |
| Nature | Architectural style | Protocol | Query language + runtime | RPC framework |
| Wire | JSON over HTTP | XML envelopes | JSON over HTTP (one endpoint) | Protobuf over HTTP/2 |
| Contract | OpenAPI (convention) | WSDL (mandatory) | Schema (built-in) | .proto (mandatory) |
| Caching | HTTP-native — its superpower | Poor | Application-level | Application-level |
| Best at | Public resource CRUD | Enterprise/legacy formality | Client-shaped nested data | Internal service speed |
| Weakness | Fixed shapes [over/underfetch](/glossary/overfetching-underfetching/) | Verbosity | Cache & rate-limit complexity | Browser friction |

The [GraphQL comparison](/glossary/graphql-vs-rest/) gets a full entry of its own.

## Conventions that make a REST API pleasant

Beyond the constraints, the conventions consumers silently grade you on: **plural-noun resources** (`/posts`, not `/getPost`); **nesting one level max** (`/posts/8fk2/comments`, then stop); **pagination on every collection** — cursor-based for depth and stability, with limits enforced; **filtering and sorting as query parameters**, not endpoint variants; **versioning** with an explicit policy (`/v1/` path or header — pick one, publish deprecation windows); **content negotiation** honored (`Accept`, `Content-Type`); and **errors as structured JSON** with a machine-readable code, not just prose. None of this is in the dissertation; all of it is in the difference between an API developers recommend and one they endure.

## Common use cases

- **Public and partner APIs** — REST's ubiquity is the feature: every language, tool, and developer speaks it.
- **Mobile and web app backends** — resource CRUD over HTTP matches how most app screens actually consume data.
- **Microservice seams** — internal contracts where HTTP's tooling (gateways, tracing, caching) earns its keep.
- **Webhook-style integrations** — systems notifying systems with plain HTTP calls both sides already understand.
- **Auto-generated data APIs** — platforms that [expose a database as REST resources](/glossary/auto-generated-database-apis/) — the fastest route from schema to working API.

## Should you use REST? A decision matrix

| REST is the right default when… | Reach for something else when… |
| --- | --- |
| Public API, unknown consumers | Internal high-throughput mesh → gRPC |
| Resource-shaped CRUD domain | Clients need to shape nested responses → GraphQL |
| HTTP caching can carry read load | Real-time bidirectional push → [WebSockets](/glossary/websockets-real-time-sync/) / [live queries](/glossary/real-time-live-queries/) |
| Simplicity and tooling breadth matter | Formal enterprise contracts required → SOAP |
| Screens map cleanly to resources | One screen aggregates five services → composite endpoint / BFF |

## Limitations and trade-offs

- **Fixed representations misfit diverse clients.** The over/underfetching pair is REST's structural weakness; sparse fieldsets and expansion parameters mitigate, GraphQL redesigns.
- **No mandatory contract.** Nothing forces an OpenAPI spec, so many REST APIs are documented by folklore; discipline is opt-in where gRPC and GraphQL make it structural.
- **Statelessness repeats context.** Auth and tenant context ride every request — cheap in bytes, but it pushes session semantics to tokens and makes some flows (multi-step transactions) awkward.
- **N+1 by design temptation.** Resource-per-URL thinking invites [one-call-per-item clients](/glossary/n-plus-one-query-problem/); good APIs ship expansion and batch affordances before consumers improvise loops.
- **"REST" the word is ambiguous.** Level-2 HTTP API in most mouths, hypermedia architecture in the dissertation — read which one a spec, job posting, or reviewer means before arguing.

## REST APIs on Back4app

Back4app is an open-source Backend-as-a-Service (BaaS) platform that combines a managed database, auto-generated REST and GraphQL APIs, authentication, file storage, and Cloud Code serverless functions. The REST API here is generated, not built: every class in your data model is immediately a resource — `POST /classes/Post` creates, `GET /classes/Post/:id` reads, with the methods, status codes, and `Location` semantics from the walkthrough above — behind keys, user tokens, and class-level permissions enforcing the boundary. The code tabs show the same cycle through the SDKs, which are thin idiomatic wrappers over exactly this HTTP; when an operation outgrows CRUD, a Cloud Code function adds a custom endpoint in one file. Level-2 REST, correct by default, from schema to URL in the time it takes to define the class.
