Skip to content
Back to skills

2943 Rest Design Rules A69236c8

ASecurity

REST APIs should focus on **resources** (nouns) rather than **actions** (verbs). The HTTP methods provide the actions.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added October 11, 2026
businessgoapidatabasesecuritydocumentation

Works with

  • cursor
  • cli
  • api

Security analysis

A100/100

Scanned October 11, 2026

npx -y skills add tools-only/X-Skills --skill 2943-rest_design_rules_a69236c8 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 2943 Rest Design Rules A69236c8?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 2943 Rest Design Rules A69236c8
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-2943-rest-design-rules-a69236c8/badge)](https://www.skillsdirectory.com/skills/tools-only-2943-rest-design-rules-a69236c8)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

SKILL.md
# REST API Design Rules Reference

## Core Principles

### 1. Resources, Not Actions
REST APIs should focus on **resources** (nouns) rather than **actions** (verbs). The HTTP methods provide the actions.

```
✅ Good:
GET    /users           # Get all users
GET    /users/123       # Get user 123
POST   /users           # Create new user
PUT    /users/123       # Update user 123
DELETE /users/123       # Delete user 123

❌ Bad:
POST   /getUsers
POST   /createUser
POST   /updateUser/123
POST   /deleteUser/123
```

### 2. Hierarchical Resource Structure
Use hierarchical URLs to represent resource relationships:

```
/users/123/orders/456/items/789
```

But avoid excessive nesting (max 3-4 levels):

```
❌ Too deep: /companies/123/departments/456/teams/789/members/012/tasks/345
✅ Better:   /tasks/345?member=012&team=789
```

## Resource Naming Conventions

### URLs Should Use Kebab-Case
```
✅ Good:
/user-profiles
/order-items
/shipping-addresses

❌ Bad:
/userProfiles
/user_profiles
/orderItems
```

### Collections vs Individual Resources
```
Collection:   /users
Individual:   /users/123
Sub-resource: /users/123/orders
```

### Pluralization Rules
- Use **plural nouns** for collections: `/users`, `/orders`
- Use **singular nouns** for single resources: `/user-profile`, `/current-session`
- Be consistent throughout your API

## HTTP Methods Usage

### GET - Safe and Idempotent
- **Purpose**: Retrieve data
- **Safe**: No side effects
- **Idempotent**: Multiple calls return same result
- **Request Body**: Should not have one
- **Cacheable**: Yes

```
GET /users/123
GET /users?status=active&limit=10
```

### POST - Not Idempotent
- **Purpose**: Create resources, non-idempotent operations
- **Safe**: No
- **Idempotent**: No
- **Request Body**: Usually required
- **Cacheable**: Generally no

```
POST /users              # Create new user
POST /users/123/activate # Activate user (action)
```

### PUT - Idempotent
- **Purpose**: Create or completely replace a resource
- **Safe**: No
- **Idempotent**: Yes
- **Request Body**: Required (complete resource)
- **Cacheable**: No

```
PUT /users/123  # Replace entire user resource
```

### PATCH - Partial Update
- **Purpose**: Partially update a resource
- **Safe**: No
- **Idempotent**: Not necessarily
- **Request Body**: Required (partial resource)
- **Cacheable**: No

```
PATCH /users/123  # Update only specified fields
```

### DELETE - Idempotent
- **Purpose**: Remove a resource
- **Safe**: No
- **Idempotent**: Yes (same result if called multiple times)
- **Request Body**: Usually not needed
- **Cacheable**: No

```
DELETE /users/123
```

## Status Codes

### Success Codes (2xx)
- **200 OK**: Standard success response
- **201 Created**: Resource created successfully (POST)
- **202 Accepted**: Request accepted for processing (async)
- **204 No Content**: Success with no response body (DELETE, PUT)

### Redirection Codes (3xx)
- **301 Moved Permanently**: Resource permanently moved
- **302 Found**: Temporary redirect
- **304 Not Modified**: Use cached version

### Client Error Codes (4xx)
- **400 Bad Request**: Invalid request syntax or data
- **401 Unauthorized**: Authentication required
- **403 Forbidden**: Access denied (user authenticated but not authorized)
- **404 Not Found**: Resource not found
- **405 Method Not Allowed**: HTTP method not supported
- **409 Conflict**: Resource conflict (duplicates, version mismatch)
- **422 Unprocessable Entity**: Valid syntax but semantic errors
- **429 Too Many Requests**: Rate limit exceeded

### Server Error Codes (5xx)
- **500 Internal Server Error**: Unexpected server error
- **502 Bad Gateway**: Invalid response from upstream server
- **503 Service Unavailable**: Server temporarily unavailable
- **504 Gateway Timeout**: Upstream server timeout

## URL Design Patterns

### Query Parameters for Filtering
```
GET /users?status=active
GET /users?role=admin&department=engineering
GET /orders?created_after=2024-01-01&status=pending
```

### Pagination Parameters
```
# Offset-based
GET /users?offset=20&limit=10

# Cursor-based
GET /users?cursor=eyJpZCI6MTIzfQ&limit=10

# Page-based
GET /users?page=3&page_size=10
```

### Sorting Parameters
```
GET /users?sort=created_at          # Ascending
GET /users?sort=-created_at         # Descending (prefix with -)
GET /users?sort=last_name,first_name # Multiple fields
```

### Field Selection
```
GET /users?fields=id,name,email
GET /users/123?include=orders,profile
GET /users/123?exclude=internal_notes
```

### Search Parameters
```
GET /users?q=john
GET /products?search=laptop&category=electronics
```

## Response Format Standards

### Consistent Response Structure
```json
{
  "data": {
    "id": 123,
    "name": "John Doe",
    "email": "john@example.com"
  },
  "meta": {
    "timestamp": "2024-02-16T13:00:00Z",
    "version": "1.0"
  }
}
```

### Collection Responses
```json
{
  "data": [
    {"id": 1, "name": "Item 1"},
    {"id": 2, "name": "Item 2"}
  ],
  "pagination": {
    "total": 150,
    "page": 1,
    "pageSize": 10,
    "totalPages": 15,
    "hasNext": true,
    "hasPrev": false
  },
  "meta": {
    "timestamp": "2024-02-16T13:00:00Z"
  }
}
```

### Error Response Format
```json
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "The request contains invalid parameters",
    "details": [
      {
        "field": "email",
        "code": "INVALID_FORMAT",
        "message": "Email address is not valid"
      }
    ],
    "requestId": "req-123456",
    "timestamp": "2024-02-16T13:00:00Z"
  }
}
```

## Field Naming Conventions

### Use camelCase for JSON Fields
```json
✅ Good:
{
  "firstName": "John",
  "lastName": "Doe",
  "createdAt": "2024-02-16T13:00:00Z",
  "isActive": true
}

❌ Bad:
{
  "first_name": "John",
  "LastName": "Doe",
  "created-at": "2024-02-16T13:00:00Z"
}
```

### Boolean Fields
Use positive, clear names with "is", "has", "can", or "should" prefixes:

```json
✅ Good:
{
  "isActive": true,
  "hasPermission": false,
  "canEdit": true,
  "shouldNotify": false
}

❌ Bad:
{
  "active": true,
  "disabled": false,  // Double negative
  "permission": false // Unclear meaning
}
```

### Date/Time Fields
- Use ISO 8601 format: `2024-02-16T13:00:00Z`
- Include timezone information
- Use consistent field naming:

```json
{
  "createdAt": "2024-02-16T13:00:00Z",
  "updatedAt": "2024-02-16T13:30:00Z",
  "deletedAt": null,
  "publishedAt": "2024-02-16T14:00:00Z"
}
```

## Content Negotiation

### Accept Headers
```
Accept: application/json
Accept: application/xml
Accept: application/json; version=1
```

### Content-Type Headers
```
Content-Type: application/json
Content-Type: application/json; charset=utf-8
Content-Type: multipart/form-data
```

### Versioning via Headers
```
Accept: application/vnd.myapi.v1+json
API-Version: 1.0
```

## Caching Guidelines

### Cache-Control Headers
```
Cache-Control: public, max-age=3600        # Cache for 1 hour
Cache-Control: private, max-age=0          # Don't cache
Cache-Control: no-cache, must-revalidate   # Always validate
```

### ETags for Conditional Requests
```
HTTP/1.1 200 OK
ETag: "123456789"
Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

# Client subsequent request:
If-None-Match: "123456789"
If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT
```

## Security Headers

### Authentication
```
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Authorization: Basic dXNlcjpwYXNzd29yZA==
Authorization: Api-Key abc123def456
```

### CORS Headers
```
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
```

## Rate Limiting

### Rate Limit Headers
```
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1640995200
X-RateLimit-Window: 3600
```

### Rate Limit Exceeded Response
```json
HTTP/1.1 429 Too Many Requests
Retry-After: 3600

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "API rate limit exceeded",
    "details": {
      "limit": 1000,
      "window": "1 hour",
      "retryAfter": 3600
    }
  }
}
```

## Hypermedia (HATEOAS)

### Links in Responses
```json
{
  "id": 123,
  "name": "John Doe",
  "email": "john@example.com",
  "_links": {
    "self": {
      "href": "/users/123"
    },
    "orders": {
      "href": "/users/123/orders"
    },
    "edit": {
      "href": "/users/123",
      "method": "PUT"
    },
    "delete": {
      "href": "/users/123",
      "method": "DELETE"
    }
  }
}
```

### Link Relations
- **self**: Link to the resource itself
- **edit**: Link to edit the resource
- **delete**: Link to delete the resource
- **related**: Link to related resources
- **next/prev**: Pagination links

## Common Anti-Patterns to Avoid

### 1. Verbs in URLs
```
❌ Bad: /api/getUser/123
✅ Good: GET /api/users/123
```

### 2. Inconsistent Naming
```
❌ Bad: /user-profiles and /userAddresses
✅ Good: /user-profiles and /user-addresses
```

### 3. Deep Nesting
```
❌ Bad: /companies/123/departments/456/teams/789/members/012
✅ Good: /team-members/012?team=789
```

### 4. Ignoring HTTP Status Codes
```
❌ Bad: Always return 200 with error info in body
✅ Good: Use appropriate status codes (404, 400, 500, etc.)
```

### 5. Exposing Internal Structure
```
❌ Bad: /api/database_table_users
✅ Good: /api/users
```

### 6. No Versioning Strategy
```
❌ Bad: Breaking changes without version management
✅ Good: /api/v1/users or Accept: application/vnd.api+json;version=1
```

### 7. Inconsistent Error Responses
```
❌ Bad: Different error formats for different endpoints
✅ Good: Standardized error response structure
```

## Best Practices Summary

1. **Use nouns for resources, not verbs**
2. **Leverage HTTP methods correctly**
3. **Maintain consistent naming conventions**
4. **Implement proper error handling**
5. **Use appropriate HTTP status codes**
6. **Design for cacheability**
7. **Implement security from the start**
8. **Plan for versioning**
9. **Provide comprehensive documentation**
10. **Follow HATEOAS principles when applicable**

## Further Reading

- [RFC 7231 - HTTP/1.1 Semantics and Content](https://tools.ietf.org/html/rfc7231)
- [RFC 6570 - URI Template](https://tools.ietf.org/html/rfc6570)
- [OpenAPI Specification](https://swagger.io/specification/)
- [REST API Design Best Practices](https://www.restapitutorial.com/)
- [HTTP Status Code Definitions](https://httpstatuses.com/)

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.