REST Principles — Resources, Verbs and Status Codes

REST (Representational State Transfer) is an architectural style for designing networked APIs. It is not a protocol or a standard but a set of constraints that, when followed, produce APIs that are predictable, cacheable, and easy for clients to consume. ASP.NET Core Web API is the .NET implementation of REST — it maps HTTP concepts (URLs, verbs, status codes, headers) to C# controllers and action methods. Understanding REST principles is the prerequisite for writing Web APIs that Angular clients, mobile apps, and third-party integrations can consume without friction.

REST Core Concepts

// ── Resources — nouns in URLs, never verbs ────────────────────────────────
// ✅ REST: resource-based URLs
GET  /api/posts              // all posts
GET  /api/posts/42           // post with id 42
GET  /api/posts/42/comments  // comments belonging to post 42
GET  /api/users/me/profile   // current user's profile

// ❌ Not REST: verb-based URLs (RPC style)
GET  /api/getPosts
POST /api/createPost
POST /api/deletePost/42

// ── HTTP verbs — each has a specific semantic meaning ─────────────────────
// GET    → Read (safe, idempotent, cacheable)
// POST   → Create (not idempotent — calling twice creates two resources)
// PUT    → Full replace (idempotent — calling twice has same effect as once)
// PATCH  → Partial update (semantically idempotent per RFC 5789)
// DELETE → Remove (idempotent — deleting the same resource twice has same result)

// ── HTTP status codes — the contract with clients ─────────────────────────
// 200 OK             — GET or PATCH succeeded; response body contains data
// 201 Created        — POST succeeded; Location header points to new resource
// 204 No Content     — DELETE or PUT succeeded; no response body
// 400 Bad Request    — client sent invalid data (validation failure)
// 401 Unauthorized   — authentication required (no or invalid token)
// 403 Forbidden      — authenticated but not authorised for this resource
// 404 Not Found      — resource does not exist
// 409 Conflict       — request conflicts with existing state (duplicate slug)
// 422 Unprocessable  — request syntax valid but business rules failed
// 500 Internal Error — unexpected server error
Note: The distinction between 401 Unauthorized and 403 Forbidden is often misunderstood. 401 means “you are not identified — please authenticate.” It should be accompanied by a WWW-Authenticate header indicating how to authenticate. 403 means “you are identified, but you do not have permission for this.” Returning 401 for a forbidden action reveals whether the resource exists (an attacker can use this to probe). Some APIs return 404 for forbidden resources to avoid this information disclosure — a debated but pragmatic choice.
Tip: Use 201 Created with a Location header after a successful POST. The Location header should contain the URL of the newly created resource: Location: https://api.blogapp.com/api/posts/43. This allows the client to immediately retrieve the created resource by following the Location URL without knowing the ID in advance. ASP.NET Core’s CreatedAtAction() and CreatedAtRoute() helpers generate this correctly.
Warning: Idempotency matters for network reliability. PUT and DELETE are idempotent — calling them multiple times has the same effect as calling once. POST is not idempotent — a retry creates a duplicate. Design your API with this in mind: if a POST endpoint creates a payment, a network retry could charge the customer twice. Use idempotency keys (client-provided unique keys) for non-idempotent operations where retries must be safe. This pattern is used by Stripe and other payment APIs.

REST URL Conventions

Operation HTTP Method URL Status Codes
List all posts GET /api/posts 200
Get post by ID GET /api/posts/{id} 200, 404
Create post POST /api/posts 201, 400, 401
Full replace post PUT /api/posts/{id} 200/204, 400, 404
Partial update post PATCH /api/posts/{id} 200, 400, 404
Delete post DELETE /api/posts/{id} 204, 404
Get post’s comments GET /api/posts/{id}/comments 200, 404
Add comment to post POST /api/posts/{id}/comments 201, 400, 404

Common Mistakes

Mistake 1 — Using GET for state-changing operations (breaks caching and bookmarks)

❌ Wrong — GET should be safe (no side effects); using it for deletes or creates is a REST violation:

GET /api/posts/42/delete   // wrong — GET must not change state!

✅ Correct — use DELETE /api/posts/42 for deletion.

Mistake 2 — Returning 200 OK for a creation (should be 201 Created)

❌ Wrong — returning 200 after POST; client cannot tell if a resource was created or retrieved.

✅ Correct — return 201 with a Location header pointing to the new resource URL.

🧠 Test Yourself

An Angular client creates a new post by sending POST /api/posts. The server creates the post with ID 43. What should the response include?