How to Mock a Service Registry in Python with an In-Memory Dict
A lightweight ServiceRegistry class backed by a dict, exposing register, unregister, lookup, list, and health-check methods.
Python code
37 linesclass ServiceRegistry:
def __init__(self):
self._services = {}
def register(self, name, endpoint, version="1.0"):
self._services[name] = {
"endpoint": endpoint,
"version": version,
"status": "healthy"
}
def unregister(self, name):
return self._services.pop(name, None)
def get_service(self, name):
return self._services.get(name)
def list_services(self):
return list(self._services.keys())
def health_check(self, name):
service = self._services.get(name)
if service:
return service["status"]
return "unknown"
if __name__ == "__main__":
registry = ServiceRegistry()
registry.register("auth-service", "http://localhost:8001")
registry.register("user-service", "http://localhost:8002", version="2.0")
print("Registered:", registry.list_services())
print("Auth:", registry.get_service("auth-service"))
print("User status:", registry.health_check("user-service"))
registry.unregister("auth-service")
print("After unregister:", registry.list_services())
print("Missing status:", registry.health_check("auth-service"))
Output
Registered: ['auth-service', 'user-service']
Auth: {'endpoint': 'http://localhost:8001', 'version': '1.0', 'status': 'healthy'}
User status: healthy
After unregister: ['user-service']
Missing status: unknown
How it works
The class wraps a plain dict (self._services) as the in-memory storage, keyed by service name. Each value is itself a small dict holding endpoint, version, and status, so get_service returns the full service metadata in one lookup. unregister uses dict.pop which returns the removed value or None if absent. health_check safely returns "unknown" when the key is missing, avoiding a KeyError. This pattern mirrors real service registries like Consul or etcd, but with zero external dependencies.
Common mistakes
- Mutating the returned dict from `get_service` and accidentally changing the registry's internal state
- Forgetting that `unregister` returns the removed service dict, which can be mistaken for a bool
- Not using a lock or threading when sharing the registry across multiple threads
Variations
- Use `defaultdict` to auto-create an empty service entry on first register
- Replace the dict with an external store like Redis for persistence across processes
Real-world use cases
- Caching service locations in a microservices demo before introducing a real discovery server.
- Simulating a registry in unit tests to verify consumer code without network calls.
- Storing dynamic endpoints for internal tools or feature flags updated at runtime.
Sponsored
More from Microservices patterns
- BFF aggregation pattern: combine multiple service responses in Python easy
- Backward Compatible Schema Evolution in Python medium
- Bulkhead Thread Pool per Service Mock in Python medium
- CQRS with Separate Read and Write Repositories in Python medium
- Cache-Aside Pattern in Python: Per-Service Mock easy
- Consumer Driven Contract Pact Mock in Python medium
Keep learning
Related tutorials and quizzes for this topic.