RESTful API Design Best Practices

Let’s look at a bad API URL example: http://example.com/api/getUserData?user_id=123&format=json

In this bad example, several issues are apparent:

  • Inadequate Naming: The endpoint name getUserData is not descriptive enough and doesn’t clearly indicate its purpose.
  • Verb in URL: The use of “get” in the endpoint violates RESTful principles, where HTTP methods like GET, POST, PUT, and DELETE should be used to indicate the action.
  • Unstructured Parameters: Query parameters are used directly in the URL without a clear hierarchy or structure, making it hard to read and maintain.
  • Explicit Format: Specifying the response format (format=json) in the URL is unnecessary, as it should be handled through the Accept header.

Good Example: GET http://api.example.com/users/123

The good example adheres to RESTful API design principles by using meaningful and structured URLs, proper HTTP methods, and leaving response format negotiation to the HTTP headers.

  • Add Versioning: The API version (v1) is included in the URL to handle versioning in a clear and structured manner.

Best Practices for API URLs

1. Use Nouns for Resources:

Use nouns to represent resources in the URL, making it intuitive and easy to understand. For example, /users for user-related operations.

2. Consistent URL Structure:

Maintain a consistent URL structure across the API to enhance predictability and ease of use. Follow a pattern like /resource/{id} for retrieving a specific resource.

3. Versioning:

Include versioning in the URL to ensure backward compatibility as the API evolves. For example, /v1/users/123.

4. Use HTTP Methods for Actions:

Utilize appropriate HTTP methods (GET, POST, PUT, DELETE) to represent actions on resources. This aligns with RESTful principles.

5. Use Hyphens for Readability:

Use hyphens (-) to separate words in URLs instead of underscores (_) or spaces. This enhances readability.

6. Hierarchy and Nesting:

Structure URLs hierarchically to represent relationships between resources. For instance, /users/123/orders to retrieve orders for a specific user.

7. Limit Parameters for Filtering:

Use query parameters for optional or additional filtering, sorting, or limiting results, rather than incorporating them directly into the URL.

8. Handle Complex Operations with Resources:

For complex operations, consider modeling them as resources. For example, /orders/123/payment to initiate a payment for an order.

References:

https://learn.microsoft.com/en-us/azure/architecture/best-practices/api-design
https://stripe.com/docs/api/subscriptions
https://stripe.com/docs/api/subscriptions
https://stripe.com/docs/api/invoices