data-driven-docs

Selft training repo


Project maintained by ggranados Hosted on GitHub Pages — Theme by mattgraham

RESTful API Design

Table of Contents


Defining Endpoints and URI Patterns

Endpoints are the specific URLs that clients use to interact with your API, and URI patterns define the structure and format of these URLs. Properly defining endpoints and URI patterns is essential for creating a consistent and user-friendly API.

Back to top

Back to top

Back to top

Back to top

Keep the URI patterns consistent throughout your API to make it easier for developers to understand and use. Predictability is also essential; users should be able to guess resource URIs based on established patterns.

Back to top

In REST, HTTP methods (GET, POST, PUT, DELETE, etc.) are used to indicate the action to be taken on a resource.

Avoid using verbs in your URI patterns, as this goes against RESTful principles.

Back to top

Clearly document your API, including the URI patterns, in your API documentation. This helps developers understand how to interact with your API and ensures consistent usage.

Example

Here’s an example of URI patterns for a simple library management API:

By following these steps and guidelines, you can define endpoints and URI patterns that make your RESTful API intuitive and easy to use for both developers and clients.

Back to top

Query Parameters and Filtering

Query Parameters

Query parameters are key-value pairs included in the URL of an HTTP request after a question mark ? and separated by ampersands &. They are used to customize the behavior of a request, such as filtering, sorting, or paginating the data. Query parameters are optional, and clients can include one or more of them in a request to tailor the response to their needs.

Common query parameters include:

Filtering

Filtering is the process of selecting a subset of resources from a collection based on specific conditions or criteria. It allows clients to narrow down their search and retrieve only the data that meets their requirements. Filtering is often accomplished using query parameters.

Example of filtering in a REST API:

Filtering can be as simple or as complex as needed, depending on the API’s capabilities and the data model.

Back to top

Validation and Security

When implementing query parameters and filtering in your REST API, it’s essential to validate and sanitize input to prevent security vulnerabilities like SQL injection or other attacks. Ensure that query parameters are validated against acceptable values and constraints.

Back to top

Documentation

Clearly document the available query parameters, their usage, and the expected behavior in your API documentation. This helps developers understand how to use filtering and query parameters effectively.

Back to top

In summary, query parameters and filtering are powerful features in a REST API that enhance its flexibility and usability. They allow clients to request specific subsets of data, sort results, paginate through large data sets, and customize their interactions with the API based on their needs. Properly implementing and documenting these features can greatly improve the developer experience and make your API more versatile.

Back to top

Pagination and Data Limiting

Pagination and data limiting are essential techniques for managing large datasets in a RESTful API. They allow clients to retrieve a subset of the data in a controlled and efficient manner, which is especially important when dealing with large collections of resources.

Pagination Basics

Pagination divides a large dataset into smaller “pages” or chunks of data, making it easier for clients to navigate through the dataset. The key components of pagination are the page and per_page parameters:

For example, if you have a collection of 100 books and you set per_page to 10, you can retrieve the first 10 books on page 1, the next 10 books on page 2, and so on.

Implementing Pagination

```http request GET /books?page=2&per_page=10

 
 - #### Calculate Offset and Limit
 In your API code, calculate the `offset` and `limit` based on the values of `page` and per_page. 
  The `offset` determines where to start fetching data, and the `limit` specifies the maximum number of items to return.

```javascript
offset = (page - 1) * per_page
limit = per_page
{
  "data": [/* Array of items */],
  "meta": {
    "page": 2,
    "per_page": 10,
    "total_pages": 10,
    "total_items": 100
  }
}  

Back to top

Handling Edge Cases

Be prepared to handle edge cases, such as when the requested page number exceeds the total number of pages or when invalid values are provided for page or per_page. You can enforce limits on per_page to prevent excessively large requests.

Back to top

Sorting and Filtering with Pagination

Clients may want to sort or filter data while paginating. Ensure that your API supports these features by allowing sorting and filtering query parameters.

Back to top

```http request GET /books?page=2&per_page=10&sort=title&filter=author:Stephen+King


<sub>[Back to top](#table-of-contents)</sub>

### Default Values

Consider providing default values for `page` and `per_page` in case clients don't specify them in their requests. This helps ensure a consistent user experience.

<sub>[Back to top](#table-of-contents)</sub>

### Caching and Optimization

 - Implement caching strategies to reduce the load on your server, especially for frequently requested pages.

   - See also: [Caching]()<!--TODO: -->
  

 - Optimize database queries to efficiently retrieve paginated data.



>Pagination and data limiting enhance the usability and performance of your API, especially when dealing with large datasets. They provide clients with control over the amount of data they retrieve while maintaining a predictable and user-friendly experience.


<sub>[Back to top](#table-of-contents)</sub>

## Versioning APIs

Versioning in RESTful APIs is a crucial aspect of API design that _allows you to introduce changes, updates, and improvements to your API while ensuring backward compatibility for existing clients_. It helps prevent breaking changes for existing consumers of your API.

### Common Approaches to Versioning REST APIs

- #### URI Versioning (Path Versioning):
In URI versioning, the API version is included directly in the URL path. This is one of the most common and straightforward approaches.


- **Example URI**: 
  - `https://api.example.com/v1/resources`


- **Advantages**: 
  - Clear and explicit versioning. 
  - Easy to implement and understand.


- **Considerations**: 
  - Ensure consistency in versioning across all API endpoints. 
  - Be mindful of backward compatibility when introducing new versions.


<sub>[Back to top](#table-of-contents)</sub>
    
- #### Accept Header Versioning
In this approach, clients specify the desired API version using the Accept header in their HTTP request.

- **Example Header**: 
  - `Accept: application/vnd.example.v1+json`
  

- **Advantages**:
  - Keeps the URI cleaner. 
  - Allows clients to request specific versions dynamically. 
  

- **Considerations**:
  - Requires clients to set the header correctly. 
  - May be less intuitive for some developers.
    

<sub>[Back to top](#table-of-contents)</sub>
    
- #### Custom Header Versioning
Similar to Accept Header Versioning, you can define a custom header specifically for versioning, such as `X-API-Version`.

- **Example Header**: 
  - `X-API-Version: 1`
  

- **Advantages**:
  - Separates versioning concerns from content negotiation. 
  - Customizable to your API's needs.


- **Considerations**:
  - Ensure that clients are aware of the custom header and use it correctly. 
    

<sub>[Back to top](#table-of-contents)</sub>
    

- #### Subdomain Versioning
In subdomain versioning, the API version is included as a subdomain in the URL.

- **Example URI**: 
  - `https://v1.api.example.com/resources`
  

- **Advantages**:
  - Provides a clear and isolated versioning structure. 


- **Considerations**:
  - Requires DNS configuration for subdomains. 
  - May be less common than URI versioning.


<sub>[Back to top](#table-of-contents)</sub>
    

- #### Query Parameter Versioning
In this approach, clients specify the API version using a query parameter.

- **Example URI**: 
  - `https://api.example.com/resources?api_version=1`
  

- **Advantages**:
  - Keeps the URI clean. 
  - Allows clients to request specific versions dynamically. 
  

- **Considerations**:
  - May not be as common or intuitive as other versioning methods. 


<sub>[Back to top](#table-of-contents)</sub>
        
    
- #### Media Type (Content-Type) Versioning
You can include the API version within the media type (e.g., JSON or XML) used for request and response bodies.

- **Example Header** 
  - `Content-Type:application/json; version=1`
  

- **Advantages**:
  - Integrates versioning with content negotiation.


- **Considerations**:
  - May require adjustments in content type parsing on the server.
    

<sub>[Back to top](#table-of-contents)</sub>
    

- #### No Versioning (HATEOAS)

In some cases, you might choose to implement **HATEOAS** (Hypertext as the Engine of Application State) instead of versioning. With HATEOAS, clients navigate the API using links provided in resource representations, reducing the need for version-specific endpoints.

- **Advantages**:
  - Allows for more flexible and self-discoverable APIs. 
  - Minimizes the need for versioning. 


- **Considerations**:
  - Requires careful design and adoption of HATEOAS principles. 
  - May not be suitable for all API scenarios.


<sub>[Back to top](#table-of-contents)</sub>
    

## HATEOAS
**HATEOAS**, which stands for "_Hypertext as the Engine of Application State_" is a constraint of the REST architectural style that _encourages the inclusion of hyperlinks within resource representations to enable clients to navigate the API dynamically_. 

HATEOAS makes an API self-discoverable and reduces the need for clients to have prior knowledge of URIs or resource relationships. 

### How to implement HATEOAS in a REST API

- #### Resource Representation with Links

When designing the representation of your API resources, include hyperlinks (links) within the resource representations. These links provide information about related resources and actions that clients can take. Links typically consist of two key components:

  - #### Rel (Relation)
    Describes the relationship between the current resource and the linked resource or action. It serves as a hint to the client about the purpose of the link.
  
  - #### Href (Hypertext Reference)
    Contains the URI to access the linked resource or perform the linked action. 

Here's an example of how a resource representation with links might look in JSON:

```json
{
  "id": 1,
  "name": "Example Resource",
  "links": [
    {
      "rel": "self",
      "href": "https://api.example.com/resources/1"
    },
    {
      "rel": "author",
      "href": "https://api.example.com/author/42"
    },
    {
      "rel": "related",
      "href": "https://api.example.com/related-resource"
    }
  ]
}

Back to top

Choose meaningful and well-defined link relation names (rels) to indicate the purpose of each link.

Back to top

Hypermedia Controls

Alongside links, you can include hypermedia controls that provide hints to clients about the actions they can perform. These controls often take the form of link templates or standardized forms that guide clients on how to construct requests for specific actions.

For example, you might include a form template for creating a new resource with predefined input fields.

{
  "id": 1,
  "name": "Example Resource",
  "controls": {
    "create": {
      "href": "https://api.example.com/resources",
      "method": "POST",
      "fields": [
        {
          "name": "name",
          "type": "text",
          "required": true
        },
        {
          "name": "description",
          "type": "text",
          "required": false
        }
      ]
    }
  }
}

Back to top

API Documentation

Document your API’s hypermedia controls and link relations in your API documentation. Clearly explain the purpose of each link and how clients should use hypermedia controls for actions. This documentation helps clients understand how to interact with your API dynamically.

Back to top

Client Implementation

Clients of your API should be designed to follow links and use hypermedia controls to discover and navigate the API’s resources and functionality dynamically. Clients can traverse links by inspecting the “rel” attribute of links and following the associated “href” to access related resources or initiate actions.

Back to top

Error Handling

Implement clear error handling and provide informative error responses that also include links to relevant resources for further actions or guidance.

Back to top


Ref.


Get Started | Web Services and API Design