REST & RESTful API Questions


Beginners To Experts


The site is under development.

Questions

Retrieve All Users via REST

<!-- Example 1: Get all users -->
GET /api/users
      

Output: Returns a JSON list of all users from the server database.

Retrieve a Specific User by ID

<!-- Example 2: Get user by ID -->
GET /api/users/1 <!-- Retrieves user with ID = 1 -->
      

Output: JSON object for user ID 1.

Create a New User

<!-- Example 3: Create user -->
POST /api/users
Content-Type: application/json
{
  "name": "Alice", <!-- New user's name -->
  "email": "alice@example.com" <!-- New user's email -->
}
      

Output: Confirmation with the new user ID and status 201 Created.

Update a User

<!-- Example 4: Update user -->
PUT /api/users/1
Content-Type: application/json
{
  "name": "Alice Updated", <!-- Updated name -->
  "email": "alice@newdomain.com" <!-- Updated email -->
}
      

Output: Confirms update with a success message or HTTP 200 OK.

Delete a User

<!-- Example 5: Delete user -->
DELETE /api/users/1 <!-- Deletes user with ID = 1 -->
      

Output: Returns success or 204 No Content.

Filter Users by Role

<!-- Example 6: Filter users with role 'admin' -->
GET /api/users?role=admin
      

Output: Returns a list of users who are admins.

Filter Products by Category

<!-- Example 7: Get products in 'electronics' category -->
GET /api/products?category=electronics
      

Output: List of electronics products.

Using PUT (Replaces Entire Resource)

<!-- Example 8: Update entire user object -->
PUT /api/users/1
Content-Type: application/json
{
  "name": "Bob", <!-- New name -->
  "email": "bob@example.com" <!-- New email -->
}
      

Output: Replaces the entire user data with new info.

Using PATCH (Partial Update)

<!-- Example 9: Update only user name -->
PATCH /api/users/1
Content-Type: application/json
{
  "name": "Bob Patch" <!-- Only updating name -->
}
      

Output: Updates only the name field of the user.

Typical REST JSON Response

<!-- Example 10: JSON structure returned -->
{
  "id": 1, <!-- Unique user ID -->
  "name": "Jane Doe", <!-- User's full name -->
  "email": "jane@example.com" <!-- Email address -->
}
      

Output: A JSON object with user details.

Token-Based Authentication Example

<!-- Example 11: Auth header with Bearer token -->
GET /api/profile
Authorization: Bearer <your-token-here>
      

Output: User profile data if token is valid; else 401 Unauthorized.

Basic Auth Example

<!-- Example 12: Basic authentication -->
GET /api/profile
Authorization: Basic dXNlcjpwYXNzd29yZA== <!-- base64(user:password) -->
      

Output: Same as above with Basic auth scheme.

Using Query Parameters for Pagination

<!-- Example 13: Paginated results -->
GET /api/users?page=2&limit=5
      

Output: Returns 5 users from page 2.

Metadata in Pagination

<!-- Example 14: Response with metadata -->
{
  "data": [...], <!-- Paginated user data -->
  "page": 2,
  "limit": 5,
  "total": 50 <!-- Total number of users -->
}
      

Output: Data + metadata about pagination.

Example of a 404 Error

<!-- Example 15: User not found -->
GET /api/users/999
      

Output:

{
  "error": "User not found", <!-- Error message -->
  "status": 404 <!-- HTTP status code -->
}
      

Example of a 400 Bad Request

<!-- Example 16: Invalid input -->
POST /api/users
Content-Type: application/json
{
  "email": "invalid" <!-- Missing name, invalid email -->
}
      

Output: Returns 400 Bad Request with validation error.

Use Plural Nouns

<!-- Good: -->
GET /api/products <!-- Refers to a collection of products -->

<!-- Bad: -->
GET /api/getProducts <!-- Verb used, not RESTful -->
      

Use Resource Nesting

<!-- Good: Get reviews for a product -->
GET /api/products/42/reviews
      

Output: Reviews for product with ID 42.

POST File with Multipart/Form-Data

<!-- Example: Upload an image file -->
POST /api/upload
Content-Type: multipart/form-data
file = <your-file.jpg>
      

Output: Upload success message with file path or URL.

Return Parent with Children

<!-- Example: Product with reviews -->
GET /api/products/42?include=reviews
      

Output:

{
  "id": 42,
  "name": "Smartphone",
  "reviews": [
    { "user": "A", "comment": "Great!" },
    { "user": "B", "comment": "Okay!" }
  ]
}
      

URL Versioning

<!-- Example 1: Version in URL -->
GET /api/v1/products
      

Header Versioning

<!-- Example 2: Version in request header -->
GET /api/products
Accept: application/vnd.api.v2+json
      

Output: Returns data according to requested API version.

Common Formats

JSON (application/json) <!-- Most widely used -->
XML  (application/xml)  <!-- Legacy or specific needs -->
HTML (text/html)        <!-- For browsers -->
CSV  (text/csv)         <!-- For exporting data -->
      

Specify Format via Accept Header

Accept: application/json <!-- Ask for JSON -->
Accept: application/xml  <!-- Ask for XML -->
      

Output: API formats data based on header.

Use Query Parameters

<!-- Example: Sort products by price ascending -->
GET /api/products?sort=price

<!-- Example: Sort descending -->
GET /api/products?sort=-price
      

Output: Sorted list of products by price.

Hypermedia As The Engine Of Application State

<!-- Example: A user object with links -->
{
  "id": 1,
  "name": "Alice",
  "links": [
    { "rel": "self", "href": "/api/users/1" },
    { "rel": "orders", "href": "/api/users/1/orders" }
  ]
}
      

Output: Clients get URLs to navigate resources dynamically.

Use Arrays in Request Body

<!-- Example: Create multiple users -->
POST /api/users/bulk
[
  { "name": "Alice", "email": "alice@example.com" },
  { "name": "Bob", "email": "bob@example.com" }
]
      

Output: Array of created users with IDs.

Use Query Parameters

<!-- Example: Filter users by status -->
GET /api/users?status=active

<!-- Example: Filter products by category and price range -->
GET /api/products?category=books&min_price=10&max_price=50
      

Output: Only items matching the filters are returned.

Use JSON Response with HTTP Status Code

<!-- Example: 404 Not Found -->
HTTP/1.1 404 Not Found
Content-Type: application/json
{
  "error": "User not found",
  "code": 404
}
      

Example: 400 Bad Request

HTTP/1.1 400 Bad Request
{
  "error": "Invalid email address"
}
      

Output: Client sees friendly error description with appropriate status.

Same Result Even if Repeated

GET /api/user/5        <!-- Safe and idempotent -->
PUT /api/user/5        <!-- Replacing resource = idempotent -->
DELETE /api/user/5     <!-- Repeated deletes still delete -->
      

Not Idempotent

POST /api/user         <!-- Creates a new user each time = not idempotent -->
      

Output: Ensures safe repeated calls for non-POST methods.

Use Tokens in Headers

<!-- Example: Bearer Token -->
Authorization: Bearer <token_here>
      

Other Options

Basic Authentication:   Authorization: Basic <base64_credentials>
API Keys:               X-API-Key: <your_key>
      

Output: API grants or denies access based on credentials.

API Versioning Keeps Backward Compatibility

<!-- Example: URL versioning -->
GET /api/v1/users
GET /api/v2/users

<!-- Example: Header versioning -->
Accept: application/vnd.example.v1+json
      

Output: Clients can choose which API version to use, preventing breaking changes.

Use HTTP Cache Headers

<!-- Example: Cache-Control header -->
Cache-Control: max-age=3600

<!-- Example: ETag for conditional requests -->
ETag: "123456789"
      

Output: Clients cache responses, reducing server load and improving speed.

Hypermedia as the Engine of Application State

<!-- Example: Include links in responses -->
{
  "user": { "id": 1, "name": "Alice" },
  "links": {
    "self": "/api/users/1",
    "orders": "/api/users/1/orders"
  }
}
      

Output: Clients navigate API dynamically via links instead of hardcoded URLs.

Prevent Abuse and Overload

<!-- Example: Response headers for rate limit -->
X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 750
X-RateLimit-Reset: 1609459200

<!-- When limit exceeded -->
HTTP/1.1 429 Too Many Requests
      

Output: Clients know usage limits and wait or retry after cooldown.

Use Nouns, Not Verbs

<!-- Good: Nouns representing resources -->
GET /api/users
POST /api/orders

<!-- Bad: Verbs in URLs -->
GET /api/getUsers
POST /api/createOrder
      

Use Plural Form

GET /api/users      <!-- preferred -->
GET /api/user       <!-- avoid singular -->
      

Output: Clean, intuitive URLs make API easier to use and maintain.

Common Security Measures

<!-- Use HTTPS to encrypt data -->
<!-- Implement Authentication and Authorization -->
Authorization: Bearer <token>

<!-- Input validation to prevent injection attacks -->
      

Output: Secure communication and access control protect API and data integrity.

PUT replaces entire resource, PATCH updates partially

<!-- PUT Example: Replace user info -->
PUT /api/users/1
{
  "name": "John",
  "email": "john@example.com"
}

<!-- PATCH Example: Update only email -->
PATCH /api/users/1
{
  "email": "newemail@example.com"
}
      

Output: PUT overwrites all fields; PATCH modifies specified fields only.

Standard HTTP Status Codes and Error Messages

<!-- Example: 404 Not Found -->
HTTP/1.1 404 Not Found
{
  "error": "User not found"
}

<!-- Example: 400 Bad Request -->
HTTP/1.1 400 Bad Request
{
  "error": "Invalid user ID"
}
      

Output: Clients understand error type and reason to handle gracefully.

Cross-Origin Resource Sharing (CORS) controls browser access

<!-- Example: CORS response header -->
Access-Control-Allow-Origin: https://example.com

<!-- Allows only specified origins to access the API -->
      

Output: Prevents unauthorized websites from making requests to your API.

Use tools and standards for clear documentation

<!-- Example: OpenAPI Specification (Swagger) -->
openapi: 3.0.0
info:
  title: User API
  version: 1.0.0
paths:
  /users:
    get:
      summary: Get all users
      responses:
        '200':
          description: Successful response
      

Output: Enables developers to understand and use the API easily.

API Versioning Strategies

<!-- URL versioning -->
GET /v1/users

<!-- Header versioning -->
Accept: application/vnd.example.v1+json

<!-- Query parameter versioning -->
GET /users?version=1
      

Output: Enables smooth upgrades and backward compatibility.

Using HTTP Cache Headers

<!-- Cache-Control header -->
Cache-Control: max-age=3600

<!-- ETag for resource validation -->
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
      

Output: Reduces server load and improves client responsiveness.

Definition and Importance

<!-- Idempotent HTTP methods: GET, PUT, DELETE -->

<!-- Multiple identical requests have same effect as one request -->
PUT /users/1
{
  "email": "new@example.com"
}
      

Output: Prevents unintended changes or duplication from retries.

Techniques and Examples

<!-- Limit requests per user/IP -->
X-Rate-Limit-Limit: 1000
X-Rate-Limit-Remaining: 750
X-Rate-Limit-Reset: 3600

<!-- Return 429 Too Many Requests when limit exceeded -->
HTTP/1.1 429 Too Many Requests
{
  "error": "Rate limit exceeded"
}
      

Output: Protects API from abuse and ensures fair usage.

Popular Testing Tools

<!-- Postman: GUI tool for manual API testing -->

<!-- curl: Command line tool for API requests -->
curl -X GET https://api.example.com/users

<!-- Automated testing frameworks -->
JUnit, Mocha, RestAssured
      

Output: Helps ensure API reliability and correctness.

Authentication Methods

<!-- Basic Authentication -->
Authorization: Basic base64(username:password)

<!-- Bearer Token Authentication -->
Authorization: Bearer your_jwt_token

<!-- OAuth 2.0 -->
POST /oauth/token
grant_type=client_credentials
      

Output: Secures API access by verifying client identity.

Hypermedia As The Engine Of Application State

<!-- Response example with HATEOAS links -->
{
  "userId": 1,
  "name": "John Doe",
  "links": [
    { "rel": "self", "href": "/users/1" },
    { "rel": "orders", "href": "/users/1/orders" }
  ]
}
      

Output: Enables clients to navigate API dynamically via hyperlinks.

API Documentation Tools

<!-- OpenAPI / Swagger -->
swagger: "2.0"
info:
  version: "1.0.0"
  title: Sample API

<!-- Example endpoint -->
paths:
  /users:
    get:
      summary: Returns list of users
      responses:
        '200':
          description: successful operation
      

Output: Provides clear, standardized API specs for developers.

Common Vulnerabilities and Mitigations

<!-- Injection attacks -->
Use parameterized queries to prevent SQL injection

<!-- Broken authentication -->
Implement strong authentication and token expiration

<!-- Data exposure -->
Use HTTPS and encrypt sensitive data
      

Output: Improves API security and protects user data.

Pagination Techniques

<!-- Query parameters for pagination -->
GET /users?page=2&limit=20

<!-- Response example with pagination info -->
{
  "page": 2,
  "limit": 20,
  "totalPages": 5,
  "users": [ ... ]
}
      

Output: Efficiently handles large datasets by returning data in chunks.

PUT vs PATCH

<!-- PUT replaces the entire resource -->
PUT /users/1
{
  "name": "Jane Doe",
  "email": "jane@example.com"
}

<!-- PATCH updates partial resource data -->
PATCH /users/1
{
  "email": "jane.doe@example.com"
}
      

Output: PUT replaces full data; PATCH modifies parts of data.

API Versioning Strategies

<!-- URI Versioning -->
GET /v1/users
GET /v2/users

<!-- Header Versioning -->
GET /users
Header: Accept-version: v1
      

Output: Maintains backward compatibility by managing API versions.

Cross-Origin Resource Sharing (CORS)

<!-- Example CORS headers -->
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Methods: GET, POST, PUT
Access-Control-Allow-Headers: Content-Type, Authorization
      

Output: Enables controlled access to resources from different domains.

Error Response Design

<!-- Example error response -->
{
  "error": {
    "code": 404,
    "message": "Resource not found",
    "details": "User with id 123 does not exist"
  }
}
      

Output: Provides clear and consistent error messages for clients.

RESTful URL Best Practices

<!-- Use nouns to represent resources -->
GET /users
GET /users/123/orders

<!-- Avoid verbs in URL -->
Avoid: /getUser or /createOrder

<!-- Use lowercase and hyphens -->
GET /order-items
      

Output: Creates clear, intuitive, and consistent API endpoints.

API Throttling

<!-- Throttling limits the number of API requests per time period -->
Example: 1000 requests per hour per user

<!-- HTTP header to indicate rate limit -->
X-Rate-Limit-Limit: 1000
X-Rate-Limit-Remaining: 750
X-Rate-Limit-Reset: 3600
      

Output: Prevents abuse and ensures fair usage of API resources.

API Caching

<!-- Use HTTP cache headers -->
Cache-Control: max-age=3600
ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"

<!-- Example response -->
GET /users/1
Response with Cache-Control header to reduce server load
      

Output: Improves API performance by reducing unnecessary requests.

API Gateway

<!-- Acts as a single entry point for multiple backend services -->
<!-- Handles request routing, authentication, rate limiting -->

Example:
Client > API Gateway > Microservices

API Gateway adds security and monitoring capabilities.
      

Output: Simplifies client interaction and centralizes cross-cutting concerns.

OAuth 2.0 Security

<!-- OAuth 2.0 flow example -->
1. Client requests authorization
2. Authorization server issues access token
3. Client uses token in API requests:
Authorization: Bearer ACCESS_TOKEN

<!-- Protects resources without sharing user credentials -->
      

Output: Enables secure delegated access to resources.

Idempotent Methods

<!-- Methods that can be called multiple times without different effects -->

PUT /users/1
DELETE /users/1
GET /users/1

<!-- Important for reliable retries and safe operations -->
      

Output: Ensures consistency and reliability in REST operations.