RESTful Resources & URI Design — Practical Guide with Examples
Resources are building blocks of RESTful APIs — business entities identified by URIs, manipulated through HTTP methods, and returned as representations to clients.
What You’ll Learn
- What resources are and how to identify them in your domain
- URI design patterns for collections, singletons, and nested resources
- Query parameters for filtering, sorting, and pagination
- HATEOAS and making APIs self-discoverable
- Common anti-patterns and how to avoid them
Why Resources Matter
In REST, everything is a resource — a user, a product, a threat report, a virus signature. How you model these resources determines whether your API is intuitive or confusing. DodaTech’s Durga Antivirus Pro API models devices, threat reports, scan jobs, and quarantine items as resources, each with clear URIs and consistent interaction patterns.
flowchart LR
A["/devices"] --> B["/devices/{id}"]
A --> C["/devices/{id}/threats"]
B --> D["/devices/{id}/scans"]
C --> E["/threats/{id}"]
E --> F["/threats/{id}/samples"]
style A fill:#dbeafe,stroke:#2563eb
style B fill:#fef3c7,stroke:#d97706
style C fill:#fef3c7,stroke:#d97706
style D fill:#fef3c7,stroke:#d97706
style E fill:#fef3c7,stroke:#d97706
style F fill:#fef3c7,stroke:#d97706
What is a Resource?
A resource is any business object that can be named and addressed. Think of resources as nouns in your API vocabulary.
Common resources include:
- Users, products, orders (e-commerce)
- Articles, comments, authors (blogging)
- Devices, threats, scan jobs, alerts (security)
Each resource gets a unique URI (Uniform Resource Identifier) that serves as its address on the web.
URI Design Patterns
Collection URI
A collection is a list of resources. Use the plural noun for the collection name.
GET /users — list all users
POST /users — create a new user
GET /users/123 — get single user
PUT /users/123 — replace user 123
PATCH /users/123 — partially update user 123
DELETE /users/123 — delete user 123The collection /users supports listing (GET) and creation (POST). Individual resources /users/{id} support retrieval, update, and deletion.
Nested Resources
When a resource belongs to or is scoped within another resource, nest the URIs:
GET /devices/{id}/threats — threats for a device
POST /devices/{id}/threats — add threat to a device
GET /devices/{id}/threats/{tid} — specific threat on a deviceHow deep should you nest? One or two levels maximum. Beyond that, the URIs become unwieldy. For deeper relationships, use query parameters or dedicated endpoints.
# Good: two levels
GET /api/v1/devices/d-123/threats HTTP/1.1
# Avoid: too deep
GET /api/v1/devices/d-123/threats/th-456/comments/cm-789Query Parameters for Filtering
Use query parameters when you need to filter, sort, or paginate collections:
GET /api/v1/threats?severity=critical&status=active&page=1&limit=20 HTTP/1.1Common query parameter patterns:
| Purpose | Example |
|---|---|
| Filtering | ?status=active |
| Multiple filters | ?type=malware&severity=high |
| Sorting | ?sort=createdAt&order=desc |
| Pagination | ?page=2&limit=50 |
| Field selection | ?fields=id,name,severity |
| Search | ?q=ransomware |
HATEOAS — Self-Discoverable APIs
HATEOAS (Hypermedia as the Engine of Application State) means API responses include links to related actions. This makes the API self-documenting and discoverable.
// GET /api/v1/devices/d-123
{
"id": "d-123",
"name": "Office-PC-7",
"os": "Windows 11",
"links": {
"self": { "href": "/api/v1/devices/d-123" },
"threats": { "href": "/api/v1/devices/d-123/threats" },
"scans": { "href": "/api/v1/devices/d-123/scans" },
"quarantine": { "href": "/api/v1/devices/d-123/quarantine" }
}
}Why HATEOAS? Without it, clients must hardcode URI patterns. With HATEOAS, the client discovers available actions dynamically. If the server changes the threat URI pattern from /devices/{id}/threats to /threats?device={id}, clients that follow links don’t break.
Common Mistakes
1. Using Verbs in URIs
/getAllUsers, /createProduct, /deleteOrder — these turn REST into RPC. The HTTP method already tells you the action. GET /users, POST /products, DELETE /orders are correct.
2. Inconsistent Naming
/users, /UserList, /get_user — inconsistent naming confuses every developer who uses your API. Stick with lowercase, plural, hyphenated nouns: /users, /products, /scan-jobs.
3. Over-Nesting
/org/org-1/projects/proj-1/tasks/task-1/comments/comment-1 is too deep. Use query parameters or flatten the hierarchy: /comments?task=task-1.
4. Not Using Plural for Collections
/user/123 suggests there’s only one user. Use /users/123 to clearly indicate this is one item from the /users collection.
5. Returning Database IDs as URIs
Exposing internal _id values couples your API to your database schema. Use UUIDs or public IDs that are separate from database internal identifiers.
6. Ignoring Content Negotiation
Clients should request the format via Accept headers, not URI extensions. /users/123.json is less RESTful than Accept: application/json.
Practice Questions
- What is a resource in RESTful API design?
- When should you use nested resources vs query parameters?
- What problem does HATEOAS solve?
- Why should resource URIs use plural nouns?
- How deep should you nest resources?
Answers:
- A resource is any business entity that can be named, addressed via a URI, and manipulated through HTTP methods.
- Use nested resources for hierarchical relationships (device owns threats); use query parameters for filtering, scoping, or cross-cutting concerns (search across all threats).
- HATEOAS decouples clients from hardcoded URI patterns. Clients discover available actions through response links, making the API more evolvable.
- Plural nouns make it clear that the URI represents a collection, with individual items addressed by appending an identifier.
- One or two levels maximum. Deeper nesting creates complex URIs that are hard to maintain and navigate.
Challenge: Design the resource URIs for Durga Antivirus Pro’s quarantine system. A quarantine has items, each item has a restore history, and each restore history entry has a reviewer. Show the URI hierarchy and explain your design choices.
FAQ
Try It Yourself
Build a list of resources for a task management app:
Collections: /tasks, /projects, /users, /labels
Nested: /projects/{id}/tasks
/users/{id}/tasks
Filtering: /tasks?status=done&project=proj-1
/tasks?dueDate=2026-06-06
Pagination: /tasks?page=2&limit=20
Sorting: /tasks?sort=dueDate&order=ascTry creating these URIs in your own API and notice how the pattern is predictable. That predictability is the power of good resource design.
What’s Next
| Topic | Description |
|---|---|
| HTTP Methods in REST | Which methods apply to which resource patterns |
| Request/Response Messages | How headers and bodies work with resources |
| RESTful APIs Overview | Review how resources fit in the REST architecture |
| GraphQL Introduction | Compare resource modeling in REST vs GraphQL |
What’s Next
Congratulations on completing this Restful Resources tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro