Topic

Hierarchy and Resource Relationships in RESTful APIs

Author

Ashen Samarakoon

27 March,2024 • 15 mins read

What is REST?

Representational State Transfer (REST) APIs are a way for different computer systems to talk to each other over the internet. They follow a set of rules called ‘REST’ to make communication easier and more organized. These APIs allow applications to request and exchange data with each other, making it possible for various services and websites to work together smoothly. It's like a standardized language that helps computers understand each other and share information effectively.

What is a resource?

In the context of RESTful APIs, a resource is any piece of information or entity that can be accessed or manipulated through the API. Resources can represent real-world objects, such as users, posts, products, or orders, as well as abstract concepts like sessions, permissions, or configurations. In a RESTful architecture, each resource is uniquely identifiable by a Uniform Resource Identifier (URI).

What are hierarchical resource structures?

In RESTful APIs, the term ‘hierarchical resource structures’ refers to the structuring of resources in a nested or tree-like structure where the resources are connected to one another. A resource is associated with each level of the hierarchy. The connections between resources are shown using URLs and HTTP methods, such as GET, POST, PUT, and DELETE. This design methodology helps develop rational, predictable, and discoverable API designs by adhering to the Representational State Transfer (REST) principles.

To ensure effective API performance and maintenance, it is essential to establish a balance and stay away from overly complex hierarchies.

Best practices for designing hierarchical resource structures

Consider an application that allows users to create posts and interact with each other through comments. Your task is to design the RESTful API to handle posts and comments efficiently. In this application, users can create posts, read posts, update posts, delete posts, and comment on posts. Each post can have multiple comments associated with it. The goal is to design a hierarchical resource structure that organizes posts and comments effectively, adhering to RESTful principles.

Now, let's explore best practices related to this hierarchical resource structure.

  1. Use Nouns in URI
    REST APIs should be designed for resources that can be entities, services, etc. Therefore, they must always be nouns. Suppose the client is asking to add resource to the collection, we can use the following request:

    • Correct -> post /comments
    • Wrong -> post /createComments

  2. Plurals or Singulars
    Generally, it is recommended to use plurals. But there is no hard rule that one cannot use singular for a REST API resource name. The ideology behind using plurals is that we are operating on one resource from a collection of resources. To depict a collection, we use plurals.
    Suppose the client is asking to retrieve a resource with the resource ID 123 from a collection of resources, the HTTP request should look like something below:
    GET /comments/123
    To add one resource to the current collection of resources, we may use the following HTTP request:
    POST /comments
    This makes your API more consistent, intuitive, and easy to understand.

  3. Hierarchical URLs
    Hierarchical URLs in RESTful APIs provide a consistent and structured way to organize resources. Just like folders in a computer's file system, hierarchical URLs arrange resources in a logical order, making them easy to find and understand.
    Consider the following example. This clearly shows the parent-child relationship between posts and comments.

    Root Resource:
    • URL: https://api.example.com/blog
    • Description: The base URL for the blog API, serving as the entry point to access various resources.
    Posts Resource:
    • URL: https://api.example.com/blog/posts
    • Description: Description: Represents the collection of blog posts.
    Single Post Resource:
    • URL: https://api.example.com/blog/posts/123
    • Description: Represents an individual blog post with an ID of 123.
    Comments Resource:
    • URL: https://api.example.com/blog/posts/123/comments
    • Description: Represents the collection of comments for the blog post with ID 123.
    Single Comment Resource:
    • URL: https://api.example.com/blog/posts/123/comments/456
    • Description: Represents an individual comment with an ID of 456 for the blog post with ID 123.

  4. HTTP Verbs
    HTTP verbs are the actions that can be performed on resources in a RESTful API. They define the type of operation being requested by the client. Here's a brief explanation of the commonly used HTTP verbs:
    • GET: Used to retrieve data from a specified resource. When a client sends a GET request to the server, it expects to receive data without causing any side effects on the server.
    • POST: Used to submit data to a specified resource. It is commonly used for creating new resources or submitting form data to the server. A POST request may result in the creation of a new resource on the server.
    • PUT: Used to update a resource or create a new resource if it does not exist. When a client sends a PUT request, it typically includes the full representation of the resource being updated or created.Used to submit data to a specified resource. It is commonly used for creating new resources or submitting form data to the server. A POST request may result in the creation of a new resource on the server.
    • DELETE: Used to remove a specified resource from the server. It is used when the client wants to delete the specified resource permanently.
    • PATCH: Used to apply partial modifications to a resource. It is similar to PUT, but instead of providing the full representation of the resource, the client sends only the changes that need to be applied.
    • HEAD: Similar to GET, but it only retrieves the headers of the response without the body. It is often used to check the status of a resource or to retrieve metadata about a resource without downloading the entire content.
    • OPTIONS: Used to retrieve the HTTP methods that are supported by a resource. It is often used by clients to determine the capabilities of a server or to check the CORS (Cross-Origin Resource Sharing) policy.

    URL HTTP Verb Purpose
    /blog/posts GET Retrieves a list of all blog posts.
    POST Creates a new blog post.
    /blog/posts/123 GET Retrieves the details of the blog post with ID 123.
    PUT/PATCH Updates the content of the blog post with ID 123.
    DELETE Deletes the blog post with ID 123.
    /blog/posts/123/comments GET Retrieve a list of all comments for the blog post with ID 123.
    POST Add a new comment to the blog post with ID 123.
    /blog/posts/123/comments/456 GET Retrieve the details of the comment with ID 456 for the blog post with ID 123.
    PUT/PATCH Update the content of the comment with ID 456 for the blog post with ID 123.
    DELETE Delete the comment with ID 456 for the blog post with ID 123.

  5. Pagination for Large Collections
    Pagination is a technique used in web development to manage large collections of data by splitting them into smaller, more manageable chunks or pages. In the context of RESTful APIs, pagination is particularly important when dealing with resources that may return a large number of results in a single request.
    When the client wants to fetch comments from a post, the client can implement pagination by using query parameters like page and limit.
    /posts/1234/comments?page=2&limit=10
    This will fetch the second page with 10 comments per page.

  6. Filtering with Query Parameters
    Filtering with query parameters in RESTful APIs allows clients to retrieve specific subsets of resources based on certain criteria. This provides flexibility and customization options for clients, allowing them to tailor API responses to their specific needs without requiring additional endpoints or complex query languages.
    To filter posts based on a specific category, use a query parameter like /posts?category=technology to retrieve all posts in the technology category.

Best practices for managing relationships

  1. Resource Embedding
    Resource embedding involves including related resources directly within the representation of a parent resource in API responses. This approach can help reduce the number of requests required to retrieve all necessary data, as clients receive complete information about related resources in a single response.
    Consider a blog API where each post can have multiple comments. When retrieving a specific post , the server embeds the comments directly within the post representation in the API response.
    GET /posts/1234

  2. Response:
    {
    "id": 1234,
    "title": "Getting Started with RESTful APIs",
    "content": "Lorem ipsum dolor sit amet...",
    "comments": [
    {
    "id": 1,
    "text": "Great article!",
    "author": "John Doe"
    },
    {
    "id": 2,
    "text": "Very informative!",
    "author": "Jane Smith"
    }
    ]
    }

  3. Hypermedia and HATEOAS
    Hypermedia As The Engine Of Application State (HATEOAS), and it is a concept that enables your API to provide links and information about the available actions and transitions for each resource. Enhancing your API's discoverability and navigability involves guiding clients through complex hierarchical resources. This approach reduces coupling and dependency between server and client.
    For example, when you fetch a user resource, you can also provide links to its sub-resources, such as posts and comments , or to its related resources, such as friends and followers.
    GET /users/1234

  4. Response:
    {
    "id": 1234,
    "name": "John Doe",
    "email": "johndoe@gmail.com",
    "links": {
    "comments": "/posts/1234/comments"
    }
    }

  5. Using Resource Identifiers
    Instead of embedding all comment details within a post response, use unique identifiers to represent relationships. This makes your API more modular, maintainable, and efficient, as you can fetch, update, or delete each resource independently, and avoid sending or receiving unnecessary data.
    For example, instead of using /posts/{id} with a nested array of comments, use /posts/{id}/comments with an array of comment ids.
    GET /posts/1234

  6. Response:
    {
    "id": 1234,
    "title": "Getting Started with RESTful APIs",
    "content": "Lorem ipsum dolor sit amet...",
    "comments": [1, 2, 3]
    }
    }

Conclusion

Designing hierarchical resource structures and managing relationships in RESTful APIs is a critical aspect of creating a robust and user-friendly API. By following the best practices outlined in this blog post and applying the examples provided, you can ensure an efficient API that enhances the developer experience and enables seamless data flow between services and applications.

With these tips and insights in mind, you are well-equipped to design APIs that stand out in the competitive landscape and drive the success of your digital initiatives.

Author

Ashen Samarakoon

Software Engineer at X-venture