How to Build a Simple Data Helper in Python for API Design
Create a beginner-friendly DataHelper class that demonstrates basic CRUD operations (add, get, list, remove) using an in-memory dictionary, ideal for learning API design concepts.
Python code
42 linesclass DataHelper:
"""Simple data helper for beginners learning API design concepts."""
def __init__(self):
self._data = {}
def add_record(self, key, value):
"""Add a record to the store."""
self._data[key] = value
return f"Added: {key} -> {value}"
def get_record(self, key):
"""Retrieve a record by key."""
if key in self._data:
return f"Found: {key} -> {self._data[key]}"
return f"Not found: {key}"
def list_records(self):
"""Return all records as a formatted string."""
if not self._data:
return "Store is empty"
return "\n".join(f"{k}: {v}" for k, v in sorted(self._data.items()))
def remove_record(self, key):
"""Remove a record by key."""
if key in self._data:
del self._data[key]
return f"Removed: {key}"
return f"Not found: {key}"
if __name__ == "__main__":
helper = DataHelper()
# Demonstrate the API design
print(helper.add_record("user1", {"name": "Alice", "age": 30}))
print(helper.add_record("user2", {"name": "Bob", "age": 25}))
print("\n" + helper.list_records())
print("\n" + helper.get_record("user1"))
print(helper.get_record("user3"))
print("\n" + helper.remove_record("user2"))
print("\n" + helper.list_records())
Output
Added: user1 -> {'name': 'Alice', 'age': 30}
Added: user2 -> {'name': 'Bob', 'age': 25}
user1: {'name': 'Alice', 'age': 30}
user2: {'name': 'Bob', 'age': 25}
Found: user1 -> {'name': 'Alice', 'age': 30}
Not found: user3
Removed: user2
user1: {'name': 'Alice', 'age': 30}
How it works
This DataHelper class wraps a plain dictionary to provide a simple, readable interface for storing and retrieving records — analogous to basic API endpoints (POST, GET, DELETE). The add_record method acts like a POST, get_record like a GET with a path parameter, and remove_record like a DELETE. Storing values as dictionaries (e.g., user profiles) mirrors how JSON payloads are handled in real REST APIs. Using sorted(self._data.items()) in list_records ensures deterministic output, which is important for predictable API responses. This pattern teaches separation of concerns: the class encapsulates state, and methods expose clear operations, a fundamental principle in API design.
Common mistakes
- Not handling missing keys explicitly — relying on KeyError instead of returning a friendly message.
- Returning raw data structures instead of formatted strings, making it harder to debug or log.
- Forgetting to use `del` correctly inside dictionaries, which can accidentally leave stale data.
Variations
- Add a method `update_record(key, value)` to modify existing entries without deleting them.
- Implement `to_json()` to serialize the store into a JSON string, simulating an API response.
Real-world use cases
- Teaching beginner developers how to build a mock REST API endpoint for CRUD operations before using frameworks like Flask or FastAPI.
- Serving as a lightweight in-memory cache or store for prototyping a microservice's data layer before connecting to a real database.
- Demonstrating basic state management in a CLI tool that needs to persist small configuration records between commands.
Sponsored
More from API design & gRPC
- Build a Bulk Array POST Mock Server in Python medium
- Build a Mock REST API with PUT and GET in Python medium
- Convert Protobuf to JSON and Dict in Python easy
- Create a Data Helper in Python for gRPC-style APIs easy
- Format data in Python using dataclasses like gRPC messages easy
- Generate an OpenAPI Spec from Mock Routes in Python easy
Keep learning
Related tutorials and quizzes for this topic.