Skip to main content

Singleton Resource

GET /users/usr_123PUT /users/usr_123PATCH /users/usr_123

A singleton resource identifies a single entity via its unique ID in the URL path. /users/123, /orders/ord_abc. GET reads it, PUT replaces it entirely, PATCH partially updates it, DELETE removes it. The ID in the URL is the permanent resource identifier.

Details

Singleton resources represent individual entities. They are accessed by appending the resource ID to the collection URL.

ID formats: use opaque string IDs (usr_123, ord_abc) rather than sequential integers where possible. Opaque IDs prevent enumeration attacks, don't expose record counts, and survive database migrations.

HTTP methods on singletons: GET /users/123 – read the user, return 200 or 404 PUT /users/123 – replace the entire user (all fields required) PATCH /users/123 – partial update (only provided fields changed) DELETE /users/123 – delete the user, return 204 No Content

PUT vs PATCH: PUT replaces the resource entirely. Missing fields are set to null or default. Use PUT when the client always sends the full representation. PATCH applies partial updates. Only the included fields change. Use PATCH for most update operations.

404 vs 403: if a resource exists but the user cannot access it, return 403 Forbidden (not 404). Returning 404 for existing-but-unauthorized resources leaks information about existence.

URL Examples

PatternDescription
GET /users/usr_123Read a specific user
PUT /users/usr_123Replace the entire user
PATCH /users/usr_123Partial update
DELETE /users/usr_123Delete the user

Do

  • +Use opaque IDs (usr_123, ord_abc) over sequential integers
  • +Return 404 for missing resources, 403 for access denied
  • +Return the updated resource in PATCH/PUT responses (client shouldn't need to re-fetch)
  • +Return 204 No Content for successful DELETE
  • +Use consistent ID format across all resources

Don't

  • !Never expose sequential integer IDs in URLs (prevents enumeration)
  • !Never return 200 for DELETE – use 204 No Content
  • !Never silently ignore unknown fields in PATCH – document behavior explicitly
  • !Never modify the resource ID after creation

Examples

PATCH singleton – partial update
PATCH /api/v1/users/usr_123
Content-Type: application/json

{ "name": "Alice Smith" }  // only name changes

---
HTTP/1.1 200 OK

{
  "id": "usr_123",
  "name": "Alice Smith",  // updated
  "email": "[email protected]"  // unchanged
}
DELETE – 204 No Content
DELETE /api/v1/users/usr_123

---
HTTP/1.1 204 No Content
// No body

See Also