Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

XS✔ ◾ improving heading sizes #9507

Merged
merged 3 commits into from
Oct 31, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 42 additions & 40 deletions rules/rest-api-design/rule.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,19 @@ redirects:

REST APIs are everywhere in our daily lives — from social media updates and online shopping to weather forecasts and GPS navigation. These interfaces allow different applications to connect seamlessly, providing the backbone for countless modern conveniences.

Building a high-quality API means adhering to best practices that enhance clarity, reliability, and security, creating a more consistent experience for developers and users.

<!--endintro-->

`youtube: https://youtu.be/_gQaygjm_hg`
**Video: Good APIs Vs Bad APIs: 7 Tips for API Design (6 min)**

## Recommendations
## Recommended configuration for most REST APIs

The following configuration is recommended for most REST APIs.
Building a high-quality API means adhering to best practices that enhance clarity, reliability, and security, creating a more consistent experience for developers and users.

### Security
### 1. Security

Most REST APIs are hosted online, and you don't want to rely on "security via obscurity". Ensure you spend time hardening your surface area.

Common sense approaches include protecting your endpoints via short-lived access tokens (even for seemingly benign functionality), as well as your typical security headers such as:

* Content-Security-Policy (CSP)
Expand All @@ -45,114 +44,117 @@ Common sense approaches include protecting your endpoints via short-lived access

Enforce HTTPS for encrypted communication and consider OAuth for user authentication and authorization, protecting against unauthorized access.

### Clear naming
### 2. Clear naming

Choose descriptive, intuitive names for endpoints and parameters following REST conventions.

* Use nouns and verbs logically (e.g., `/api/users` for accessing user data, `/api/users/{id}` for specific user information).
* Endpoints should also use plurals. i.e `/api/users` instead of `/api/user`.
* Use nouns and verbs logically (e.g., `/api/users` for accessing user data, `/api/users/{id}` for specific user information)
* Endpoints should also use plurals. i.e `/api/users` instead of `/api/user`

This provides a much more consistent API structure when querying both collections and single entities.

### Idempotent requests
### 3. Idempotent requests

Design POST, PUT, and DELETE operations as idempotent, where repeating an action yields the same result as performing it once.
This avoids unintended actions from repeated requests.
Design `POST`, `PUT`, and `DELETE` operations as idempotent, where repeating an action yields the same result as performing it once. This avoids unintended actions from repeated requests.

::: greybox
If a DELETE request removes a record, re-sending it should not throw errors if the record is already deleted.
If a `DELETE` request removes a record, re-sending it should not throw errors if the record is already deleted.
:::

::: good
Figure: Good example - This prevents accidental duplicate data processing
:::

### Pagination
### 4. Pagination

For endpoints that return lists, it's best to apply pagination to prevent overwhelming the client with too much data.

When paging parameters are omitted from the request, the API should apply some sensible defaults (e.g. page 1, 50 records).

Use query parameters like `?page=` and `?limit=` to specify page numbers and size, offering a more manageable data experience while improving performance.

### Meaningful query parameter names
### 5. Meaningful query parameter names

When supporting sorting, apply clear query strings. Query params should generally be optional making the API easier to consume.

Consistent sorting parameters allow developers to retrieve and organize data efficiently and minimize confusion in handling API responses.

::: greybox
```js
`?x=name&y=asc`
:::
```

::: bad
Figure: Bad example - it's impossible to understand what those query string mean!
Figure: Bad example - It's impossible to understand what those query string mean!
:::

::: greybox
```jsox
`?sortBy=name&order=asc`
:::
```

::: good
Figure: Good example - query strings are meaningful
Figure: Good example - Query strings are meaningful
:::

### Simple cross-resource references
### 6. Simple cross-resource references

For APIs that reference multiple resources (e.g., `userId` in a post endpoint), keep relationships simple to prevent over-complicating endpoints.

Provide clear references or IDs rather than nested data whenever possible to keep API responses readable and easy to follow.

::: greybox
```js
`api/products?user_id=123&product_id=321`
:::
```

::: bad
Figure: Bad example - messy query parameter
Figure: Bad example - Messy query parameter
:::

::: greybox
```js
`api/orders/123/items/456/products/789`
:::
```

::: bad
Figure: Bad example - overly complicated endpoint
Figure: Bad example - Overly complicated endpoint
:::

::: greybox
```js
`api/products/789`
:::
```

::: good
Figure: Good example - clearly defined endpoint
Figure: Good example - Clearly defined endpoint
:::

## Optional
## Optional configurations

These other design choices may only be required in certain circumstances. You should consider the specific use case of your API e.g. public facing or under heavy load.

### Rate limiting
### 7. Rate limiting

Rate limiting controls the number of requests per user within a time frame, protecting the API from abuse.

When adding rate limiting you should provide appropriate status codes and messages (e.g., `HTTP 429`) when limits are reached.

### Caching
### 8. Caching

* Implement caching for frequently requested data to reduce server load and response times
* Cache static data responses at the client or server side where appropriate, especially for resources that don't change frequently
* Use HTTP cache headers like `Cache-Control` and `ETag` to guide clients on when to use cached data or refresh it, balancing speed and data freshness.
* Use HTTP cache headers like `Cache-Control` and `ETag` to guide clients on when to use cached data or refresh it, balancing speed and data freshness

### Compression
### 9. Compression

Enabling compression for API responses, especially for large data payloads, reduces bandwidth and improves loading times.

* Use GZIP or Brotli compression formats, which are widely supported and effective in reducing data sizes.
* Use GZIP or Brotli compression formats, which are widely supported and effective in reducing data sizes

### Versioning
### 10. Versioning

Introduce versioning from the start (e.g., `/v1/resource`) to maintain backward compatibility when updating the API.
Versioning helps users manage changes without breaking existing implementations, allowing them to adopt new features gradually.
There are 3 common ways to implement versioning:

Versioning helps users manage changes without breaking existing implementations, allowing them to adopt new features gradually. There are 3 common ways to implement versioning:

* Route
* Query String
* Header

For more details, see this rule: [Do you provide versioning?](/do-you-provide-versioning).
For more details, see [Do you provide versioning?](/do-you-provide-versioning)