Skip to content

RESTful Resources & URI Design — Practical Guide with Examples

DodaTech Updated Jun 6, 2026 6 min read

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
  
Prerequisites: Understanding of REST and RESTful Methods. Familiarity with JSON helps.

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 123

The 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 device

How 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-789

Query 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.1

Common query parameter patterns:

PurposeExample
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

  1. What is a resource in RESTful API design?
  2. When should you use nested resources vs query parameters?
  3. What problem does HATEOAS solve?
  4. Why should resource URIs use plural nouns?
  5. How deep should you nest resources?

Answers:

  1. A resource is any business entity that can be named, addressed via a URI, and manipulated through HTTP methods.
  2. Use nested resources for hierarchical relationships (device owns threats); use query parameters for filtering, scoping, or cross-cutting concerns (search across all threats).
  3. HATEOAS decouples clients from hardcoded URI patterns. Clients discover available actions through response links, making the API more evolvable.
  4. Plural nouns make it clear that the URI represents a collection, with individual items addressed by appending an identifier.
  5. 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

Should I use /users/{id} or /user/{id}?
: Use /users/{id} (plural). The collection is /users, and individual items are identified by their ID. This is the most widely adopted convention in RESTful APIs and makes the URI hierarchy clear.
How do I handle resources that don’t fit CRUD?
: Use the POST method with a verb in the URI: POST /auth/login, POST /payments/charge. This is acceptable because these are actions, not resources. The key is being consistent and documenting where exceptions exist.
Should I version my URIs?
: Yes — include the version in the URI: /api/v1/users, /api/v2/users. This allows you to make breaking changes to the API without breaking existing clients. Version the media type (Accept: application/vnd.api.v2+json) is an alternative.
What is the difference between a URI and a URL?
: All URLs are URIs, but not all URIs are URLs. A URI identifies a resource (/users/123). A URL is a URI that also provides the means to locate it (https://api.example.com/users/123). In REST, we use URLs because we need both identification and location.

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=asc

Try 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

TopicDescription
HTTP Methods in RESTWhich methods apply to which resource patterns
Request/Response MessagesHow headers and bodies work with resources
RESTful APIs OverviewReview how resources fit in the REST architecture
GraphQL IntroductionCompare 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