Skip to content

5 Common REST API URI Design Mistakes That Break Your API Architecture

Why does your REST API feel fragile, hard to evolve, and tightly coupled to your database? The problem often starts with URI design. I’ve seen the same five mistakes repeat across projects—verbs in URIs, database mirroring, chatty APIs, deep nesting, and singular collections. Each one breaks the REST model in a different way.

Mistake 1: Using Verbs Instead of Nouns

This is the most common mistake. Developers treat URIs like function names.

Mistake
POST https://api.contoso.com/create-order
POST https://api.contoso.com/delete-customer/5
GET https://api.contoso.com/get-products

Why is this wrong? HTTP methods already define actions. POST creates, DELETE removes, GET retrieves. When you put verbs in URIs, you’re duplicating information and breaking REST conventions. A URI should identify a resource, not describe an operation.

Correct
POST https://api.contoso.com/orders
Content-Type: application/json
{"productId": 2, "quantity": 4, "customerId": 1}
DELETE https://api.contoso.com/customers/5
GET https://api.contoso.com/products

The URI identifies the resource. The HTTP method defines what you do with it. This separation makes your API predictable and consistent.

Mistake 2: Mirroring Database Table Structure

Your database has tables. Your API has resources. These are not the same thing.

Mistake
GET https://api.contoso.com/database/orders_table
GET https://api.contoso.com/tables/users/join/roles_view

When you expose database tables directly, you create several problems. First, you increase your attack surface—hackers can probe your schema through your API. Second, you leak implementation details that should stay internal. Third, any database refactoring breaks your API contract.

Correct
GET https://api.contoso.com/orders/99
GET https://api.contoso.com/users/5/roles

Model business entities, not storage structures. Your API should represent what the application does, not how it stores data. Add a mapping layer between your database and API to isolate changes. When you rename a table or split it across shards, your API stays stable.

Mistake 3: Creating Chatty APIs

Some developers go too far in the opposite direction—creating a separate endpoint for every attribute.

Mistake
GET https://api.contoso.com/orders/1/value
GET https://api.contoso.com/orders/1/products
GET https://api.contoso.com/orders/1/status
GET https://api.contoso.com/orders/1/customer

This forces clients to make multiple requests for related data. Each round-trip adds latency. Under load, this pattern kills performance. Your servers handle more requests than necessary, and your clients waste bandwidth.

Correct
GET https://api.contoso.com/orders/1
Response:
{
"id": 1,
"value": 199.99,
"status": "shipped",
"products": [...],
"customer": {...}
}

Denormalize related data into larger resources. But don’t go to extremes either—fetching a 500KB payload when you need an ID is equally problematic. Find the balance based on how clients actually use your data.

Mistake 4: Nesting Relationships Too Deep

Deep hierarchies seem logical until you try to maintain them.

Mistake
GET https://api.contoso.com/customers/1/orders/99/products/5/variants/12
DELETE https://api.contoso.com/customers/1/orders/99/products/5/variants/12/images/7

URIs like this are hard to parse, cache, and evolve. When your business model changes—and it will—you’ll break every client using these endpoints. The Azure Architecture Center recommends keeping URIs simpler than collection/item/collection.

Correct
GET https://api.contoso.com/customers/1/orders
GET https://api.contoso.com/orders/99/products
GET https://api.contoso.com/products/5/variants/12

Flatten your hierarchy. Use HATEOAS links in responses to guide clients to related resources. This keeps your URIs short and gives you flexibility to restructure relationships without breaking clients.

Mistake 5: Mixing Up Singular and Collection URIs

Consistency matters. When you mix singular and plural nouns, routing becomes confusing.

Mistake
GET https://api.contoso.com/customer # Collection endpoint?
GET https://api.contoso.com/customers/5 # Item endpoint
GET https://api.contoso.com/order/5 # Inconsistent naming
GET https://api.contoso.com/products # Now plural?

This confuses developers and breaks conventions. Frameworks expect collection/{id} patterns for routing.

Correct
GET https://api.contoso.com/customers # Collection
GET https://api.contoso.com/customers/5 # Item from collection
GET https://api.contoso.com/orders # Collection
GET https://api.contoso.com/orders/5 # Item from collection
GET https://api.contoso.com/products # Collection
GET https://api.contoso.com/products/5 # Item from collection

Use plural nouns for collections. This convention makes your API predictable: /resource-name for the collection, /resource-name/{id} for a specific item. Everyone knows what to expect.

Summary

In this post, I covered five URI design mistakes that break REST APIs. Verbs in URIs ignore what HTTP methods already express. Database mirroring couples your API to implementation details. Chatty APIs kill performance with unnecessary round-trips. Deep nesting creates unmaintainable hierarchies. Inconsistent singular/plural naming breaks developer expectations. Fix these by designing around business entities with plural nouns, keeping hierarchies simple, and using HTTP methods for actions. Your API becomes easier to evolve, more secure, and more performant.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments