Mastering API Design: From Basics to Rate Limiting, Versioning, and Security
This article shares practical insights on API design, covering fundamentals, rate limiting, version management, security considerations, and inter‑team integration, illustrated with code snippets and diagrams to help developers build clear, standardized, and robust backend interfaces.
Honestly, I wish I had seen this article earlier; back in college I followed a free tutorial and built a shopping mall, proudly adding it to my résumé.
I still remember how that e‑commerce tutorial defined interfaces: regardless of add, modify, delete, or query with parameters, everything was a POST request, like the example below.
修改用户的收货地址
POST /xxx-mall/cart/update_addressIt seems the use of POST everywhere was for convenience in passing parameters.
At that time I had no awareness of the need to design API interfaces.
After that embarrassing experience, I realized the importance of exposing my shortcomings to mentors for guidance, much like seeking internships during university.
This article skips the formal definition of API concepts and instead shares personal insights in a conversational style, divided into five sections:
Introduction to APIs
API Rate Limiting
API Version Management
API Permissions and Security
Inter‑team API Integration
1. Introduction to APIs
When I first learned web development, backend tutorials taught us to render templates, meaning the backend returns full HTML pages and the browser only renders them.
Typically a template corresponds to a route, e.g., to view user information you would navigate to: https://ajun24.com/user Back then I thought routes were the whole concept of APIs.
Most backend tutorials also introduce AJAX on the frontend, showing how to send asynchronous requests that usually return JSON data rather than HTML pages.
This distinction became clear during my internship when I learned about front‑end and back‑end separation.
However, for teaching convenience, complete projects often still use template rendering.
Even after learning AJAX, I wondered whether all data could be fetched via such asynchronous calls.
During my internship, a front‑end colleague reminded me that API definitions should be done before development.
He also noted that deletion should not use POST requests.
My mentor then suggested I study REST‑style API design.
Since that incident, I’ve learned to expose my gaps to those willing to help, just as seeking internships reveals the skills the industry needs.
In formal interviews, we should clearly explain state transitions, but here I’ll refer to REST‑style APIs as “readable APIs”.
GET /users # query user info
PATCH /users/{user_id} # partially update user infoFollowing conventions makes APIs instantly understandable, like speaking a technical jargon.
If an API is only used by nearby colleagues, a simple chat may suffice, but when many external systems call it, proper documentation is essential.
Bad documentation feels like reading a cryptic tome.
Good API docs act like tool manuals, reducing learning cost and encouraging usage.
Thus, learning API conventions, writing docs, and developing accordingly forms a solid workflow.
2. API Rate Limiting
After an API is built, it cannot be called infinitely due to system and network limits.
Most cloud providers expose rate limits, e.g., 30 calls per second per user.
Designing rate limiting is essential for user‑facing APIs.
First, identify system bottlenecks. If the API relies on internal components like databases or message queues, load testing can reveal maximum capacity. If it depends on external services, the “wooden bucket” principle applies.
For a monolithic deployment, a simple token‑bucket algorithm suffices. Below is a minimal implementation:
"""
Simple explanation:
Implement a fixed‑capacity bucket that refills tokens at a constant rate.
When an operation needs a token, it consumes one; if none are available, it waits.
"""
class TokenBucket(object):
# rate is the token generation speed, capacity is the max tokens
def __init__(self, rate, capacity):
self._rate = rate
self._capacity = capacity
self._current_amount = 0
self._last_consume_time = int(time.time())
# token_amount is the number of tokens required per operation
def consume(self, token_amount):
# Increment tokens based on elapsed time
increment = (int(time.time()) - self._last_consume_time) * self._rate
self._current_amount = min(increment + self._current_amount, self._capacity)
if token_amount > self._current_amount:
return False
self._last_consume_time = int(time.time())
self._current_amount -= token_amount
return TrueIn modern companies, services are often deployed in clusters behind load balancers, so the simple token‑bucket code must be adapted for distributed environments, typically implemented at the proxy layer or via API gateways.
Many cloud providers offer API gateway services that handle rate limiting centrally.
3. API Version Management
After covering basics and rate limiting, let’s discuss API versioning.
Just like software, APIs evolve; to avoid breaking existing clients, we should keep old versions unchanged.
We can embed the version in the URL, e.g.: GET /api/v1/users # query user info When a new version is needed:
GET /api/v2/users # query detailed user infoIf we add a new endpoint without versioning, we might end up with ambiguous routes like /get_user_info, forcing us to create a new path later.
4. API Permissions and Security
Now consider permission and security.
In production, APIs must enforce authentication; exposing an API publicly without checks leads to rapid failure.
Permission checks can be categorized into three approaches:
IP whitelist – suitable for fixed internal clients.
Token‑based authentication – common for B2B services.
User login – typical for consumer‑facing applications.
Security also influences API design. For example, instead of exposing a raw user ID: GET /users/287435/orders we can use a safer endpoint: GET /users/me/orders Overall, API design must follow standards while addressing business‑specific security needs.
5. Inter‑team API Integration
Finally, APIs enable data sharing across teams in the data‑driven era.
When another team requests to call your API, multiple considerations arise, such as clarity, rate limits, and permission.
Can you understand my API?
Don’t overload my API!
APIs must be used with proper authorization.
Although my exposure to the broader data ecosystem is limited, summarizing these technical points helps keep APIs usable and secure.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
21CTO
21CTO (21CTO.com) offers developers community, training, and services, making it your go‑to learning and service platform.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
