Apidog

All-in-one Collaborative API Development Platform

API Design

API Documentation

API Debugging

API Mocking

API Automated Testing

Resources in REST APIs: Clearly Explained

Iroro Chadere

Iroro Chadere

Updated on May 20, 2025

In modern web development, Representational State Transfer (REST) APIs have become the de facto standard for building web services that are scalable, maintainable, and easy to understand. At the very heart of any RESTful API lies a fundamental concept: the resource. Understanding what resources are, how they are identified, and how we interact with them is paramount to designing and consuming REST APIs effectively. This article will delve deep into the nature of resources in REST APIs, exploring their characteristics, their relationship with collections, and the common operations performed on them.

The core idea behind REST is that an API exposes a set of resources, and clients interact with these resources by sending requests to their unique identifiers. But what exactly constitutes a "resource"? In the context of a REST API, a resource can be almost anything you can name. It could be a tangible entity like a customer, a product, or an order. It could also be an abstract concept such as a service, a transaction, or a calculation. The key is that it’s an item of interest that can be identified and manipulated.

Think of the internet itself as a vast collection of resources. Every webpage, image, video, or document you access online is a resource, each with its own unique address (URL). REST APIs adopt this same philosophy. Whether it's a user profile on a social media platform, a specific book in an online library, or a weather forecast for a particular city, each is a resource that the API makes available.

💡
Want a great API Testing tool that generates beautiful API Documentation?

Want an integrated, All-in-One platform for your Developer Team to work together with maximum productivity?

Apidog delivers all your demans, and replaces Postman at a much more affordable price!
button

Identifying Resources: The Role of URIs

Crucially, every resource in a REST API must have at least one unique identifier. This identifier is typically a Uniform Resource Identifier (URI). The most common form of a URI used in web APIs is a Uniform Resource Locator (URL), which not only identifies the resource but also provides a means of locating it.

For example, in an API for managing a blog, a specific blog post might be identified by a URI like /posts/123. Here, /posts likely represents a collection of posts, and 123 is the unique identifier for a particular post within that collection. Similarly, a user resource might be identified by /users/john.doe.

The design of these URIs is a critical aspect of API design. Well-designed URIs are intuitive, predictable, and easy for developers to understand and use. They should act as a clear signpost, indicating the nature of the resource being accessed. Good practice dictates using nouns to represent resources (e.g., /products, /orders) rather than verbs (e.g., /getProducts, /createOrder). The HTTP methods (GET, POST, PUT, DELETE) are then used to specify the action to be performed on the resource identified by the URI.

Resource vs. Representation: A Key Distinction

It's important to understand the difference between a resource and its representation. A resource is the conceptual entity itself – the actual "thing" (the customer, the product, the idea). A representation, on the other hand, is a snapshot of the state of that resource at a particular point in time, typically formatted in a specific media type like JSON (JavaScript Object Notation) or XML (eXetensible Markup Language).

When a client requests a resource from an API, it doesn't receive the resource itself (which is an abstract concept residing on the server). Instead, it receives a representation of that resource. For example, if you request /users/jane.doe, the API might return a JSON representation like:JSON

{
  "id": "jane.doe",
  "firstName": "Jane",
  "lastName": "Doe",
  "email": "jane.doe@example.com",
  "dateJoined": "2023-01-15T10:00:00Z"
}

This JSON object is not Jane Doe herself; it's a representation of her data as stored by the system. The same resource could potentially have multiple representations. For instance, the API might also be capable of providing an XML representation of the same user if requested by the client through content negotiation (using HTTP headers like Accept).

The state of a resource can change over time. If Jane Doe updates her email address, the underlying user resource changes. Subsequent requests for /users/jane.doe will then return a new representation reflecting this updated state. This is where the "State Transfer" part of REST comes into play: clients interact with resources by retrieving and manipulating their state through these representations.

Collections: Resources That Contain Other Resources

Often, resources are grouped together into collections. A collection is itself a resource. For example, /posts in our blog API is a collection resource that contains individual post resources. Similarly, /users would be a collection of user resources.

When a client sends a GET request to a collection URI like /products, the API typically returns a representation that lists the member resources within that collection, often with some summary information for each. This list might look something like:JSON

[
  {
    "id": "prod_abc",
    "name": "Laptop Pro 15",
    "price": 1299.99,
    "link": "/products/prod_abc"
  },
  {
    "id": "prod_xyz",
    "name": "Wireless Mouse Ergonomic",
    "price": 39.99,
    "link": "/products/prod_xyz"
  },
  // ... more products
]

Notice how each item in the collection often includes a link (or its own URI) to the individual resource, allowing the client to navigate to and retrieve the full details of a specific product if needed.

Designing URIs for collections and their members follows a logical pattern. Typically:

  • /resources refers to the collection (e.g., /orders).
  • /resources/{id} refers to a specific member within that collection (e.g., /orders/567).

This hierarchical structure makes the API intuitive and aligns with the conceptual relationship between the collection and its elements.

Operations on Resources and Collections

Interaction with resources and collections in a REST API is achieved through standard HTTP methods. These methods define the actions to be performed. The most common methods are:

GET: Used to retrieve a representation of a resource or a collection.

  • GET /posts would retrieve a list of all posts (the collection).
  • GET /posts/123 would retrieve the specific post with ID 123. GET requests should be safe, meaning they should not have any side effects on the server; they are purely for retrieving data. They should also be idempotent, meaning multiple identical GET requests should have the same effect as a single request (i.e., return the same representation, assuming the resource hasn't changed in the meantime).

POST: Primarily used to create a new resource within a collection. The request body typically contains the representation of the new resource to be created.

  • POST /posts with a request body containing the details of a new blog post (e.g., title, content, author) would instruct the server to create that new post. The server usually responds with a 201 Created status and often includes the URI of the newly created resource in the Location header of the response. POST requests are generally not safe (as they create a new resource) and are not idempotent (multiple identical POST requests will typically create multiple new resources). POST can also be used for other non-idempotent operations that don't neatly fit other HTTP methods, such as triggering a process or sending data for processing where the outcome isn't simply an update to an existing identifiable resource.

PUT: Used to update an existing resource completely. The request body should contain the full new representation of the resource. If the resource identified by the URI exists, it is replaced with the new representation. If it doesn't exist, some APIs might choose to create it (though this behavior can vary).

  • PUT /posts/123 with a request body containing the updated title and content for post 123 would replace the existing post 123 with the new data. PUT requests are not safe (as they modify a resource) but are idempotent. Sending the same PUT request multiple times should result in the same state for the resource. For example, updating a post's title to "New Title" multiple times still results in the title being "New Title".

DELETE: Used to remove a resource.

  • DELETE /posts/123 would delete the blog post with ID 123. DELETE requests are not safe (they remove data) but are idempotent. Deleting a resource multiple times should have the same outcome as deleting it once (the resource is gone). Subsequent DELETE requests to the same URI might return a 404 Not Found or a 204 No Content.

PATCH: Used to partially update an existing resource. Unlike PUT, which requires the client to send the entire representation of the resource, PATCH allows for sending only the changes. For example, to update only the email address of a user, a PATCH request would only need to include the new email.

  • PATCH /users/jane.doe with a request body like {"email": "new.email@example.com"} would update only Jane's email address, leaving other fields like her name unchanged. PATCH requests are not safe. Their idempotency can be debated and depends on the nature of the patch operation. For example, a PATCH operation that says "append '!' to the description" is not idempotent, whereas "set the description to 'new value'" is.

Singleton Resources

While collections and their members are common, sometimes a resource is a standalone entity, often referred to as a "singleton" resource. A good example might be the configuration of a specific application or the current status of a system.

For instance, /application/configuration could be a URI for a singleton resource representing the application's configuration settings. A GET request to this URI would retrieve the current configuration, and a PUT request could be used to update it. There isn't a "collection" of configurations in this context; there's just the configuration.

Similarly, /system/status could represent the current operational status of the system.

Best Practices for Designing Resource-Based APIs

Designing a resource-centric API involves more than just identifying entities and mapping them to URIs. Several best practices contribute to a robust and user-friendly API:

  1. Use Nouns for URIs: As mentioned earlier, resource URIs should be nouns (e.g., /products, /users/{userId}/orders). Verbs should be reserved for HTTP methods.
  2. Consistent URI Naming: Use a consistent naming convention for your URIs. Plural nouns are generally preferred for collections (e.g., /customers instead of /customer). Use hyphens (-) to improve readability of long path segments (e.g., /product-categories) rather than underscores (_) or camelCase.
  3. Keep URIs Simple and Hierarchical: Design URIs that reflect the relationships between resources. For example, /users/{userId}/accounts/{accountId} clearly shows that an account belongs to a user. However, avoid overly deep nesting, which can make URIs unwieldy.
  4. Statelessness: Each request from a client to the server must contain all the information needed to understand1 and process the request. The server2 should not store any client context between requests. This is a core principle of REST and contributes to scalability.
  5. Leverage HTTP Methods Correctly: Use GET, POST, PUT, DELETE, and PATCH according to their defined semantics. Don't use GET to modify data or POST to retrieve data when GET is appropriate.
  6. Use HTTP Status Codes Appropriately: Return standard HTTP status codes to indicate the outcome of a request (e.g., 200 OK, 201 Created, 204 No Content, 400 Bad Request, 401 Unauthorized, 403 Forbidden,3 404 Not Found, 500 Internal Server Error). This provides clear feedback to the client.
  7. Support Content Negotiation: Allow clients to specify the desired representation format (e.g., JSON, XML) using the Accept header and indicate the format of the request body using the Content-Type header.
  8. Versioning: Plan for API evolution by implementing a versioning strategy (e.g., /v1/products). This allows you to introduce breaking changes without affecting existing clients.
  9. Provide Meaningful Error Representations: When an error occurs, return a useful error message in the response body (typically JSON or XML) that explains what went wrong.
  10. Hypermedia as the Engine of Application State (HATEOAS): While not always fully implemented, HATEOAS is a key principle of REST. It means that representations of resources should include links (hypermedia controls) that allow clients to discover related actions and resources. For example, a representation of an order might include links to cancel the order, view its shipment status, or see the products it contains. This makes the API more self-discoverable.

The Granularity of Resources

One common design challenge is determining the appropriate granularity of your resources. Should an address be a separate resource, or part of a user resource? Should order items be distinct resources, or embedded within an order resource?

There's no single right answer; it depends on the specific use cases and how clients will typically interact with the data.

  • Separate Resources: If an entity (like an address) can be independently created, retrieved, updated, or deleted, or if it's shared among multiple other resources, it often makes sense to model it as a separate resource with its own URI (e.g., /addresses/{addressId}). You can then link it from other resources (e.g., a user resource might have an addressId field or a link to /addresses/{addressId}).
  • Embedded Resources/Sub-resources: If an entity is tightly coupled to a parent resource and doesn't have an independent lifecycle, it might be better modeled as part of the parent resource's representation or as a sub-resource accessible via a path like /users/{userId}/address. This can simplify client interactions if the sub-entity is always accessed in the context of its parent.

The choice often involves trade-offs:

  • Chattiness: Many fine-grained resources might lead to more HTTP requests (increased chattiness) if a client needs to assemble a complete picture from multiple sources.
  • Data Duplication/Complexity: Embedding resources can lead to larger payloads and potential data duplication or complexity if the embedded information is also available as a standalone resource.
  • Cacheability: Separate resources are often easier to cache independently.
  • Atomicity of Operations: Updates to a single, coarse-grained resource are inherently atomic. Managing atomicity across multiple fine-grained resource updates can be more complex.

Careful consideration of these factors, along with a deep understanding of how the API will be used, is crucial for making the right decisions about resource granularity.

💡
Want a great API Testing tool that generates beautiful API Documentation?

Want an integrated, All-in-One platform for your Developer Team to work together with maximum productivity?

Apidog delivers all your demans, and replaces Postman at a much more affordable price!
button

Conclusion

Resources are the foundational building blocks of any RESTful API. They represent the "things" that an API exposes and allows clients to interact with. By assigning unique URIs to resources, differentiating between a resource and its representation, and organizing resources into logical collections, developers can create APIs that are intuitive, scalable, and adhere to the principles of REST.

Understanding how to define, identify, and manipulate resources using standard HTTP methods is essential for both API designers and consumers. Coupled with best practices in URI design, appropriate use of HTTP status codes, and a thoughtful approach to resource granularity, a well-defined resource model leads to APIs that are not only functional but also a pleasure to work with. As the digital landscape continues to evolve, the principles of resource-oriented architecture will remain a cornerstone of effective web service communication.

What is Document360? And Top 5 Document360 AlternativesViewpoint

What is Document360? And Top 5 Document360 Alternatives

Document360 is a popular knowledge base tool, but it's not the only option. In this guide, we explore what makes Document360 unique, and introduce 5 top Document360 alternatives like Apidog, Notion, and Docusaurus to help you find the right fit for your documentation needs in 2025.

Emmanuel Mumba

May 20, 2025

What is “Docs as Code”? How To Write Code Documentation (Best Practices)Viewpoint

What is “Docs as Code”? How To Write Code Documentation (Best Practices)

💡Want a great API Testing tool that generates beautiful API Documentation? Want an integrated, All-in-One platform for your Developer Team to work together with maximum productivity? Apidog delivers all your demans, and replaces Postman at a much more affordable price! button What is “Docs as Code”? In the ever-evolving landscape of software development, the importance of clear, concise, and maintainable documentation cannot be overstated. Traditionally, documentation has often been an a

Ismail Kamil

May 20, 2025

Open Banking API: Clearly ExplainedViewpoint

Open Banking API: Clearly Explained

In an increasingly interconnected digital world, the financial services industry is undergoing a profound transformation. At the heart of this evolution lies Open Banking, a concept powered by Application Programming Interfaces (APIs) that is reshaping how consumers and businesses interact with their financial data and services. Open Banking APIs are the invisible engines driving this change, enabling secure data sharing, fostering innovation, and ultimately empowering users with greater control

Mark Ponomarev

May 20, 2025