REST (Representational State Transfer) is an architectural style for designing networked APIs. RESTful services use HTTP methods, status codes, and resource-based URLs.

Resource Naming

Use nouns, not verbs. Use plural names:

  GET    /api/users           — list users
GET    /api/users/123       — get user 123
POST   /api/users           — create user
PUT    /api/users/123       — replace user 123
PATCH  /api/users/123       — partial update
DELETE /api/users/123       — delete user 123

GET    /api/users/123/orders — user's orders (nested resource)
  

Avoid:

  POST /api/createUser        ✗ verb in URL
GET  /api/getUserById/123   ✗ verb in URL
POST /api/users/delete/123  ✗ wrong method
  

HTTP Methods

Method Idempotent Safe Body Purpose
GET Yes Yes No Read
POST No No Yes Create
PUT Yes No Yes Full replace
PATCH No No Yes Partial update
DELETE Yes No No Remove

Status Codes

Code Meaning When
200 OK Successful GET, PUT, PATCH
201 Created Successful POST
204 No Content Successful DELETE
400 Bad Request Validation error
401 Unauthorized Missing/invalid auth
403 Forbidden Authenticated but not allowed
404 Not Found Resource doesn’t exist
409 Conflict Duplicate, version conflict
422 Unprocessable Entity Semantic validation error
500 Internal Server Error Server failure

Request/Response Format

  // POST /api/users
// Request
{
  "name": "Alice Smith",
  "email": "[email protected]"
}

// Response 201 Created
{
  "id": 123,
  "name": "Alice Smith",
  "email": "[email protected]",
  "createdAt": "2024-01-15T10:30:00Z"
}

// Error response 400
{
  "error": "Validation failed",
  "details": [
    { "field": "email", "message": "must be a valid email address" }
  ]
}
  

Pagination, Filtering, Sorting

  GET /api/users?page=0&size=20&sort=name,asc&active=true
  
  {
  "content": [ ... ],
  "page": 0,
  "size": 20,
  "totalElements": 150,
  "totalPages": 8
}
  

Versioning

  URL path:     /api/v1/users, /api/v2/users
Header:       Accept: application/vnd.myapp.v1+json
Query param:  /api/users?version=1
  

URL path versioning is the most common and explicit approach.

HATEOAS (Hypermedia)

Include links to related actions:

  {
  "id": 123,
  "name": "Alice Smith",
  "_links": {
    "self": { "href": "/api/users/123" },
    "orders": { "href": "/api/users/123/orders" },
    "update": { "href": "/api/users/123", "method": "PUT" }
  }
}
  

Spring HATEOAS provides this via EntityModel and CollectionModel.

API Design Checklist

  • Use consistent naming conventions (plural nouns, kebab-case URLs)
  • Return appropriate HTTP status codes
  • Include error details in a consistent format
  • Support pagination for collection endpoints
  • Version your API from the start
  • Document with OpenAPI/Swagger

Best Practices

  • Design APIs around resources, not database tables
  • Use DTOs — never expose entity internals directly
  • Validate input at the controller layer
  • Return 201 with Location header on resource creation
  • Use PATCH for partial updates, PUT for full replacement
  • Keep URLs lowercase with hyphens: /api/order-items, not /api/orderItems