Skip to main content
RESTful Principles
CHAPTER 10 Beginner

REST URL Design Best Practices

Updated: May 13, 2026
5 min read

# CHAPTER 10

REST URL Design Best Practices

1. Introduction

The URL is the face of your API. Just like a well-organized website is easy to navigate, a well-designed REST API is intuitive for developers to use without constantly checking documentation. In Chapter 10, we will synthesize what we learned about resources and endpoints to establish strict best practices for naming conventions, handling complex relationships, and maintaining a clean resource hierarchy.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Establish consistent naming conventions for API endpoints.
  • Design URLs for nested, relational data (One-to-Many).
  • Understand when a URL is "too deep" and how to flatten it.
  • Differentiate between filtering via URL paths vs Query strings.
  • Apply consistent casing (kebab-case) to API routes.

3. Beginner-Friendly Explanation

Imagine a folder structure on your computer. You might have a folder called Photos. Inside that, you have 2023. Inside that, Vacation. If someone asks you for a specific photo, you tell them: /Photos/2023/Vacation/image.jpg.

REST URLs work the exact same way. We organize data into broad folders (Resources), and use IDs to pinpoint specific files. /authors (Broad folder) /authors/5 (Specific author) /authors/5/books (Books belonging to that specific author)

4. Real-World Examples

  • Stripe API: To manage subscriptions for a specific customer, Stripe uses a logical hierarchy: /customers/{customer_id}/subscriptions.
  • Twitter API: To get the followers of a specific user: /users/{user_id}/followers.

5. Detailed Code Examples

In a PHP routing setup, you need to extract the IDs dynamically from the URL path.
php
12345678910111213141516171819
<?php
// Example: Parsing a hierarchical URL like /authors/5/books
$uri = $_SERVER[&#039;REQUEST_URI'];
$method = $_SERVER[&#039;REQUEST_METHOD'];

// Regex to match /authors/{id}/books
if (preg_match(&#039;/^\/authors\/([0-9]+)\/books$/', $uri, $matches)) {
    $authorId = $matches[1];
    
    if ($method == &#039;GET') {
        echo json_encode(["message" => "Fetching books for Author ID: $authorId"]);
    } elseif ($method == &#039;POST') {
        echo json_encode(["message" => "Creating a new book for Author ID: $authorId"]);
    }
} else {
    http_response_code(404);
    echo json_encode(["error" => "Endpoint not found"]);
}
?>

6. Request/Response Examples

When designing URLs, keep relationships clear. If you want to delete a specific book belonging to an author, you could use a deeply nested URL, but flattening is usually better.

Nested (Acceptable but long): DELETE /authors/5/books/12

Flattened (Best Practice for direct operations): DELETE /books/12 *(Since Book 12 has a globally unique ID, we don't actually need to specify the author in the URL to delete it!)*

7. HTTP Examples

Let's map out a complete URL design for a Blog API:
  • GET /posts (All posts)
  • POST /posts (Create post)
  • GET /posts/14 (View post 14)
  • GET /posts/14/comments (View comments ON post 14)
  • POST /posts/14/comments (Add a comment to post 14)
  • DELETE /comments/99 (Delete a specific comment directly)

8. JSON Examples

When returning relational data, the URL design often influences the JSON output structure.

GET /authors/5/books

json
12345678
{
  "author_id": 5,
  "author_name": "J.K. Rowling",
  "books": [
    {"id": 101, "title": "Sorcerer&#039;s Stone"},
    {"id": 102, "title": "Chamber of Secrets"}
  ]
}

9. Best Practices

  • Use Kebab-Case: For multi-word resources, use hyphens. e.g., /user-profiles is better than /userProfiles or /user_profiles.
  • Max Depth of 2: Avoid going deeper than resource/id/resource. A URL like /countries/us/states/ca/cities/sf/streets is an anti-pattern. If relationships are that deep, use query parameters or flatten the endpoints.
  • Never expose database logic: Do not name endpoints like /users/findByEmail or /db_users_table. Hide the implementation details behind clean resource names.

10. Common Mistakes

  • Mixing Plurals and Singulars: Having /user to create, but /users to list. It should ALWAYS be /users.
  • Using File Extensions: An endpoint should be /users, not /users.php or /users.json. The Accept header dictates the format, not the URL.

11. Mini Exercises

  1. 1. Refactor this bad URL design: GET /getAllActiveAdminUsers
*(Answer: GET /users?role=admin&status=active)*
  1. 2. Refactor this too-deep URL: GET /authors/5/books/12/chapters/3
*(Answer: GET /chapters/3)*

12. Coding Challenges

Challenge 1: Write the 5 core RESTful endpoints (HTTP Method + URL path) required to manage "Categories" in an e-commerce API.

13. MCQs with Answers

Question 1

Which is the industry standard casing for API URLs?

Question 2

How deep should REST URL nesting generally go?

Question 3

If you want to get a specific comment (ID 4) on a specific post (ID 10), what is the most robust, flattened URL?

14. Interview Questions

  • Q: Explain why URLs should not be deeper than two levels of nesting, and how to resolve deep relationship queries.
  • Q: Why do we use query strings (like ?status=active) instead of separate endpoint paths (like /users/active) for filtering?
  • Q: Is it acceptable to use file extensions like .json in API URLs? Why or why not?

15. FAQs

Q: If I change my URL design later, won't it break client apps? A: Yes! Changing an API URL is a "breaking change." This is why API Versioning (e.g., putting /v1/ in the URL) is critical, which we will cover in a later chapter.

Q: Should endpoints be localized (translated)? A: Generally, no. API URLs are intended for developers, not end-users. Stick to English for endpoints (e.g., /users), even if the actual data returned is in Spanish or French.

16. Summary

In Chapter 10, we polished our URL design skills. We learned to use plural nouns, kebab-case, and keep our nesting shallow. We discovered that when relationships get too deep, we should flatten our URLs to target the unique ID of the resource directly. Clean URLs are the foundation of a developer-friendly API.

17. Next Chapter Recommendation

You may have noticed we used a question mark ? in some examples to filter data. Proceed to Chapter 11: Query Parameters and Filtering to learn how to make your list endpoints dynamic and searchable.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·