Api Design
Api Design
🟣 API Design interview questions and answers to help you prepare for your next software architecturea and design
patterns interview in 2024.
[Link]/
Star Notifications
You can also find all 50 answers here 👉 [Link] - API Design
2. Standardization: Establishes common rules and formats, ensuring consistent interactions. This centralizes
and streamlines processes, making them easier to implement and manage.
3. Decoupling: Separates components, allowing them to evolve independently. This means that when an
underlying system changes, its API can remain largely unaffected, as long as the external interface is
maintained.
4. Reusability: Encapsulates functionality in a modular form, making it portable across different systems or
applications.
5. Security and Access Control: Provides methods for authentication, ensuring that only authorized users
or software can interact with the API. It also centralizes security management, which can be more
effective than securing each component individually.
6. Consolidation of Data and Services: Aggregates data or services from different sources, presenting a
unified view to the consumer. This is particularly valuable in distributed systems where diverse data may
be located across multiple servers or cloud services.
2. Can you explain the difference between an API and a Web service?
APIs and web services both facilitate communication between two distinct systems, but they do so in
different ways.
API
An API is primarily focused on enabling communication between a web service and a client application. It
typically has narrower scopes and may offer functions or methods as clear-cut entry points.
Web Service
A web service, on the other hand, is more expansive, enabling interaction not just with clients, but also with
other softwares, resulting in a more comprehensive service-oriented architecture.
Key Differences
Data and Functionality Exposure: Web services are primarily concerned with data (often XML or JSON)
and don't explicitly expose business logic. APIs are more varied, offering data and functionality.
Communication Protocols: Web services aren't tied to a particular communication protocol, while
RESTful APIs typically use HTTP, and SOAP-based services frequently use standard protocols like SMTP
and TCP.
Interface Structure: A web service often adheres to standard data formats and protocols, like XML,
SOAP, or WSDL. Meanwhile, APIs can employ more varied structuring mechanisms like REST and
GraphQL.
[Link] 2/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Ease of Use: APIs are generally more user-friendly, with direct HTTP calls and often a common shorthand
standard for responses (like JSON). Web services can be more complex, requiring specific tooling,
protocols, and data formats.
Security Focus: Web services have a stronger focus on security and are often wrapped in layers of
security protocols.
Building Blocks
Endpoints: API calls are made to specific URLs known as endpoints. Similarly, web services have URLs to
which different actions are tied.
Methods: APIs often have different methods for different operations (e.g., POST for creating, GET for
reading, etc.). In contrast, web services typically incorporate a single method, known as POST , to handle
various types of operations.
Request/Response: Both APIs and web services function around requests and responses.
import requests
import requests
from datetime import datetime
print([Link])
[Link] 3/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Key Principles
1. Client-Server Separation: The client and server are independent. The client is responsible for the
interface and user experience, while the server manages resources and data storage.
2. Statelessness: Each client request to the server should contain all necessary information for the server to
fulfill the request. The server doesn't store client state between requests.
3. Cacheability: Responses from the server should be explicitly marked as cacheable or non-cacheable.
Cache control mechanisms standardize this process.
4. Layered System: API systems can be composed of multiple layers (intermediaries), such as gateways and
proxies. The client doesn't need to know the exact location of the server, allowing for improved
scalability and security.
5. Uniform Interface: All capabilities of a REST API can be accessed using a standard command-
independent interface like HTTP methods (GET, POST, PUT, DELETE), status codes, and content types
(e.g., JSON or XML).
6. Code on Demand (Optional): This concept is often described as the ability to transfer executable code
from the server to the client. While not a required constraint, it can be seen in specific interactions, such
as web apps modifying behavior based on in-browser scripts.
Real-World Application
For instance, imagine a weather service API that uses RESTful design. A client like a weather application
running on a user's device sends a request to the API server for weather information.
The server processes the request, which includes a specific endpoint for the type of data needed ("resource"),
a cache duration to indicate how long the data can be stored, expected file types (e.g., JSON), and a standard
HTTP method like GET.
Upon successful handling of the request, the server responds with the requested weather data. The response
is marked as cacheable, and it complies with the standards set for available content types.
This approach lets us handle resources independently, establishes clear communication between the client
and the server, and simplifies the intricacies of delivering web services.
[Link] 4/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Core Concepts
Key Distinctions
Data Format
Ease of Consumption
SOAP: Comprehensive, stable, but raises complexity with formal contracts, WSDL usage, and tight
coupling.
REST: Promotes loosely coupled, simple interactions that are often easier for developers to understand
and employ.
SOAP: Insists on adhering to WSDL (Web Services Description Language) to define the structure and
behavior of the web service.
REST: Lacks a universal standard or formal contract.
Error Handling
SOAP: Definitive standards for error representations using dedicated XML elements.
REST: Generally employs HTTP status codes for error communication.
State Management
[Link] 5/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Integrations
SOAP: Initially built with a focus on integrating remote systems and enabling inter-machine
communication.
REST: Evolved within the web for serving web resources, focusing on human-readable URLs for web APIs.
[Link](true);
try (OutputStream os = [Link]()) {
byte[] input = [Link](StandardCharsets.UTF_8);
[Link](input, 0, [Link]);
}
import requests
url = "[Link]
headers = {"Content-Type": "application/json", "Authorization": "Bearer YOUR_TOKEN"}
data = {"param1": "value1", "param2": "value2"}
if response.status_code == 200:
# Successful request, process data here
response_data = [Link]()
[Link] 6/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
else:
print(f"Request failed with status code: {response.status_code}")
Main Components
1. Endpoint URI: A unique HTTP or HTTPS address that identifies the API resource. It typically comprises
the host, base path, and perhaps additional path segments to specify the resource.
2. HTTP Methods: Also known as request methods, these define the type of action the HTTP request
should perform. Common methods include GET , POST , PUT , DELETE , and more.
3. Data Format: This refers to how the sent and received data are structured. APIs commonly use JSON or
XML for data transmission.
Crucial Aspects
Request Headers: Provide additional information about the client or the request.
Request Payload: The data sent in the request body, generally applicable to HTTP methods like POST and
PUT.
General Structure
An API endpoint typically follows a RESTful or non-RESTful design.
RESTful Design:
Non-RESTful Design:
[Link] 7/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
using System;
using [Link];
using [Link];
class Program
{
private static readonly HttpClient client = new HttpClient();
6. What are the common methods (HTTP verbs) used in a REST API,
and what does each method do?
REST, which stands for Representational State Transfer, employs a set of HTTP verbs for specific actions on
resources. Each method is designed for a particular purpose.
HTTP Verbs
1. GET (Read): Retrieves specific data, typically a resource or a collection of resources.
2. POST (Create): Submits data to the server to create a new resource. This is often used in forms on
websites.
3. PUT (Update): Modifies a specific resource using its unique identifier. It's less common in web forms.
4. PATCH (Partial Update): Applies partial modifications to a resource. This is used when you want to
update an existing resource with more granular details (e.g., user profile update without sending entire
user object).
[Link] 8/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
6. HEAD: Requests the headers of resources, similar to GET without the message body.
7. OPTIONS: Communicates capabilities and allowed HTTP methods for a specific resource. This is helpful
for scenarios where a client isn't certain of available actions.
8. TRACE: Echoes the request, which can be useful for diagnostics or to ensure that proxies do not change
the request. However, it's often disabled due to security concerns.
10. Custom Verbs: In more specialized cases, custom HTTP verbs can be defined. However, using well-
known methods makes it easier for other developers to understand and interact with your API.
import [Link].*;
import [Link].*;
@Path("/books")
public class BookResource {
@GET
@Path("/{id}")
public Response getBook(@PathParam("id") int id) {
// Logic to retrieve and return a book with the given ID
}
@POST
@Path("/create")
public Response createBook(Book book) {
// Logic to validate and create a new book
}
README
@PUT
@Path("/update/{id}")
public Response updateBook(@PathParam("id") int id, Book updatedBook) {
// Logic to update the book with the given ID
}
@DELETE
@Path("/remove/{id}")
public Response deleteBook(@PathParam("id") int id) {
// Logic to delete the book with the given ID
}
@OPTIONS
@Path("/options/{id}")
public Response getOptionsForBook(@PathParam("id") int id) {
// Logic to provide available options/actions for the book with the given ID
}
}
[Link] 9/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
In the example above, the Java code utilizes JAX-RS annotations to define RESTful API endpoints and map
each method to the corresponding HTTP verb.
This method is straightforward as it clearly indicates version in the URL. For example:
/api/v1/resource
/api/v2/resource
However, it can lead to cluttered URLs and might be too rigid for evolving APIs.
/api/resource?version=1
This approach is flexible but can pose caching and security challenges.
Content Negotiation
application/[Link].v1+json
application/[Link].v2+json
Recommendations
[Link] 10/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Backwards Compatibility (BC), where possible, is critical for API longevity. If new features can be added in a
way that does not break existing client functionality, that is the most desirable outcome. It's also important to
consider how various clients use your API, and make sure that managing those changes does not present
difficulties for them. If breaking backward compatibility is necessary, provide migration guides and give users
time to adapt.
Clear Documentation is Key: When versioning, provide transparent, easy-to-follow documentation. Any
changes or deprecations should be well-documented to support developers transitioning to a new version.
Also, it's important to keep in mind that not everyone will be using the latest version of your API, and some
clients might never transition to a newer version. This will potentially require you to support older versions
for an extended time period.
app = Flask(__name__)
@[Link]('/api/v1/resource')
def resource_v1():
return "This is v1 of the resource"
@[Link]('/api/v2/resource')
def resource_v2():
return "This is v2 of the resource"
if __name__ == '__main__':
[Link]()
In this example, a client can call either /api/v1/resource or /api/v2/resource to access the respective
resource version.
[Link](3000, () => {
[Link]('Server running on port 3000');
});
In this example, a client passes the desired version in the 'api-version' header to access the resource.
Error Recovery: Idempotent operations help in recovering from transient errors and ensure that failed
requests can be safely retried.
Request Safety: Especially vital when using protocols like HTTP, this feature prevents undesirable side
effects that may result from accidental or unexpected re-execution of requests.
Cost and Efficiency: Idempotence saves resources and prevents duplicate work, essential for operations
that might be costly or time-consuming.
User Experience: By ensuring predictable and consistent outcomes, idempotence enhances the reliability
and user experience of applications.
The DELETE method, aimed at removing a resource, can also be made idempotent, signaling that either the
resource is no longer present or that repeated deletion requests don't affect its state.
Implementing Idempotence
Request-Identifier Combo
You can achieve idempotence through the use of a unique request identifier for client actions. The server
checks this identifier to see if the request is a duplicate.
[Link] 12/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
import uuid
server_side_state = {
'/update_resource': {'etag': '123'}, # The ETag acts as the request identifier
}
def update_resource(request_body):
resource_etag = server_side_state['/update_resource']['etag']
client_provided_etag = request_body.get('etag')
Timestamp or Nonce
Using a timestamp or nonce is another way to ensure that requests are unique, especially in distributed
systems. The server stores past timestamps or nonces and compares them to the request to identify
duplicates.
import time
server_side_state = {
'/place_order': set(),
}
def place_order(request_id):
# Check if the request ID has been seen before within a certain timeframe
if request_id in server_side_state['/place_order']:
return 409, "Duplicate Request"
# If this is a new request, add it to the set and process the order
server_side_state['/place_order'].add(request_id)
# Client side
def make_request_to_server():
# Assuming the client generates a unique request ID
request_id = str(uuid.uuid4())
[Link] 13/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
response_code, response_message = place_order(request_timestamp)
if response_code == 200:
print("Order placed successfully!")
else:
print(f"Order placement failed: {response_message}")
Maintaining server state about previous requests allows for efficient handling of duplicates. The state can be
stored in-memory or persisted in a database. The server ensures that a subsequent request with the same
identifier and parameters doesn't lead to redundant processing.
import [Link];
import [Link];
9. Can you explain what API rate limiting is and give an example of
why it might be used?
API Rate Limiting sets constraints on the number of requests a client can make within specific timeframes.
These measures ensure that servers are not overwhelmed and that resources are shared fairly.
[Link] 14/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
1. Threshold: Defines the maximum number of requests within a specific timeframe that a client can make.
2. Time Window: The duration for which the threshold is measured (for example, 100 requests per hour).
[Link]('/api/', apiLimiter);
In this example, our Express server sets a rate limit of 100 requests every 15 minutes for all endpoints under
/api . When the limit is exceeded, the client receives an HTTP 429 status with the specified message.
Key Roles
Resource Owner: The user who has ownership and control over the resources.
Resource Server: Hosts the protected user data and is capable of accepting and responding to requests
for these resources.
Client: The application that requests access to resources from the resource server.
[Link] 15/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Authorization Server: Verifies the client's identity and issues access tokens uniquely tied to a specific
client and resource server.
Core Workflow
1. The client requests authorization by sending the user to the authorization server.
2. The authorization server authenticates the user and obtains authorization.
1. The client uses the access token to make requests on behalf of the user.
2. The resource server validates the token and, if valid, permits access to the requested resources.
Benefits of OAuth
Security: Credentials are not shared, reducing the risk of exposure.
Consent: Users have granular control over what data is shared.
Limited Scope: Access tokens are often time-bound and restricted in scope.
Ease of Management: Access can easily be revoked and managed, enhancing user privacy.
Behavioral Changes: These changes can be equally disruptive to existing clients. For example, stateless
services suddenly requiring a session, such as the introduction of a mandatory authToken for all
requests, can't be directly handled. If such changes are necessary, it's best to make them opt-in or
gradual.
[Link] 16/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Data Model Evolution: Data models naturally evolve over time. To maintain backward compatibility, it's
crucial to allow for both old and new data formats. This can be achieved through field deprecation,
versioned endpoints, or providing mappings to older formats where applicable.
Response Changes: Altering the structure or content of API responses can quickly disrupt consuming
applications. Where feasible, such changes should be additive - meaning new fields are introduced
without altering existing ones. If removal is essential, it should be gradual or made opt-in.
Data Consistency: Ensuring consistency, particularly in multi-step operations, can be challenging across
versions. Adopting idempotent methods can mitigate issues stemming from data inconsistencies.
Error Handling: Be consistent with error codes and messages. Newer versions can introduce additional
error codes, but it's essential to avoid changing or removing existing ones.
app = Flask(__name__)
books = [{"id": 1, "title": "1984", "author": "George Orwell"}]
@[Link]("/api/v1/books", methods=["GET"])
def get_books_v1():
return jsonify({"books": [book["title"] for book in books]})
@[Link]("/api/v2/books", methods=["GET"])
def get_books_v2():
return jsonify({"books": books})
if __name__ == "__main__":
[Link]()
In this example, the /api/v1/books endpoint returns only book titles (this might be the original behavior),
while the /api/v2/books endpoint returns full book objects. Both versions coexist, allowing older clients to
receive just titles while providing new functionality to clients using the latest version.
12. What are some common response codes that an API might return,
and what do they signify?
HTTP, the foundation of API communication, uses status codes to indicate the outcome of a client's request.
These codes enable the client app to respond effectively.
1xx - Informational
100: Continue
101: Switching Protocols
[Link] 17/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
102: Processing
2xx - Success
200: OK
201: Created
202: Accepted
204: No Content
206: Partial Content
207: Multi Status
208: Already Reported
226: IM Used
3xx - Redirection
[Link] 18/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Map HTTP methods to specific actions to maintain consistency. For instance, use GET for data retrieval,
POST for data creation, PUT or PATCH for data modifications, and DELETE for data removal.
Follow a consistent pattern for endpoint naming. For instance, to get user data, the endpoint could be
/users/{id} .
Keep the input/output data structures consistent across various endpoints. Using JSON for data
representation is a common and efficient practice.
For endpoints returning lists, incorporate pagination (using parameters like page and limit ) and filtering
(like name or status ) to ensure the stability and manageability of the responses.
By including a version number in the URL, such as /v1/endpoint , you empower clients with the ability to
transition to newer versions of your API when changes are introduced.
Consider using unique endpoints when actions are independent, and shared endpoints when there's a clear
resource connection. For example:
On Method Overloading
[Link] 19/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
However, if you need to support multiple actions on a single resource, it could look like this:
Instead of numerous endpoints with slight variations, leverage query parameters for flexibility. For example,
instead of:
GET /cars/verified
GET /cars/active
Use a format such as: GET /cars?status=verified where possible. This streamlined approach not only
maintains a cleaner endpoint structure but also eases the cognitive load on clients when learning and using
the API.
While it's common to expect plurals with endpoints representing collections, catering to both forms can
enhance accessibility. An endpoint could manage this by using:
app = Flask(__name__)
# RESTful - Preferred
@[Link]('/users', methods=['POST'])
[Link] 20/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
def create_user_restful():
data = [Link]
user_id = max([Link](), default=0) + 1
users[user_id] = data
return jsonify({'id': user_id}), 201
if __name__ == '__main__':
[Link]()
14. When designing an API, how would you document it for end-users?
API documentation is crucial for its ease of use. It serves as a comprehensive guide for developers to
understand how the API functions and how to interact with it.
Self-Documenting APIs
Modern languages like Python and Java allow for self-documentation in APIs. By including code, developers
can see documentation in real-time with tools such as:
Javadoc: Key for Java, this tool integrates shifted HTML comments into Java source code.
Doxygen: Suitable for multiple languages, it processes structured comments to generate a range of
outputs.
Implementing self-documentation in your API codebase ensures documentation remains up-to-date and in
sync with the codebase.
Graphical Representation
"Visual Documentation" or API diagrams present a system of resources, their relationships, data flows, and
function descriptions in an easy-to-grasp graphical format.
[Link] 21/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Postman: Helps designers visualize APIs with a dedicated user interface, easing the integration process.
API Workbench: An interactive "IDE" for developing APIs that supports API lifecycle management.
class Student:
"""
A simple student class.
Attributes:
name (str): The name of the student.
age (int): The age of the student.
subjects (list of str): The subjects the student is enrolled in.
"""
Args:
name (str): The name of the student.
age (int): The age of the student.
subjects (list of str, optional): The subjects the student is enrolled in.
"""
[Link] = name
[Link] = age
[Link] = subjects if subjects else []
Args:
new_subject (str): The name of the new subject to enroll in.
"""
[Link](new_subject)
In this Python class, you can see well-documented attributes, methods, and the class itself using structured
comments that can be extracted by documentation tools.
Utilizes offset to specify a starting point and a limit to define the number of records to return.
Simple to implement but can lead to performance issues, especially with very large datasets.
2. Keyset Pagination
Uses key attributes, such as the record's unique identifier, to establish the starting point for the next
set of results.
Often efficient but requires attributes to be monotonic to ensure coverage and avoid duplication.
3. Timestamp Pagination
Applies a timestamp associated with the record to decide where to start and how far back to go.
Straightforward and adept at handling constantly changing datasets.
4. Cursor-Based Pagination
Pavilion - Employs cursors, usually in the form of encoded tokens, to pinpoint the current position in
the dataset.
Efficient and doesn't suffer from drawbacks like the "skipping" behavior of offset-based paging.
5. Hybrid Paging
The flexibility of databases often allows for a combination of the above methods based on specific
application requirements.
The size of the dataset, its volatility, and distribution can all impact selection. For instance, a dataset
with frequently inserted or removed records might benefit from cursor-based paging to maintain
consistency.
The selectivity of the data attributes is another vital consideration: Keyset and timestamp-based
paging work best with unique and ordered attributes, while cursor-based methods might be more
adaptable with non-unique attributes.
If your data has strong relationships that need to be maintained across paginated sets, key-driven
methods are often preferred.
3. Performance Considerations
Before choosing a method, test its performance with sets of various sizes and data configurations.
Each method influences security and caching differently. It's important to evaluate how caching and
security mechanisms integrate with your chosen approach.
5. Client Complexity
[Link] 23/24
4/10/25, 3:51 PM GitHub - Devinterview-io/api-design-interview-questions: 🟣 API Design interview questions and answers to help you prepare for y…
Consider the ease of use for API consumers; some methods may introduce additional complexities
to client code.
6. Ordering Requirements
If a specific order (e.g., chronology) is mandated, ensure that the chosen method can reliably deliver
results in that order.
7. Error Handling
The likelihood and resolution of errors during pagination can differ between methods.
Data structures evolve, potentially making a once-reliable key unsuitable for continued paging.
9. Environmental Limitations
Some platforms or tooling might best integrate with particular pagination techniques.
Continually evaluate how the chosen method satisfies both present and foreseeable future criteria.
return {
"data": results,
"links": {
"next": f"/resource?start={next_start}&end={next_end}&limit={limit}"
}
Releases
No releases published
Packages
No packages published
[Link] 24/24