I am playing with my simple personal project – a simple REST API application and I am currently struggling with a kind of design problem.
How to insert an operation ID (request ID, an identifier of each operation) into each “layer”?
Let’s say I have a
UserRepository trait (interface) with 2 implementations (say,
Database), which is used by multiple services (say,
UpdateUserService). All these services are then used by a facade, let’s say the
UserFacade. This facade is called by the CLI tool or the Users REST handler.
What I would like to be able to do is to create a unique Operation ID for each “operation” (request or a CLI call). This ID would be used for logging across the whole application, I would like to be able to access it in the repositories, services and facade. Later I would like to access the logs and trace how the request was processed by each of the layers.
Possible solutions that come to my mind are:
Pass this operation ID to each method as an additional parameter. I
consider this ugly since the interface would be polluted by the extra parameter, unrelated to the business logic.
Create a whole structure of facades and services using the operation ID (the ID will be provided to each instance via the constructor for each request or CLI
action). I like this approach but I think this would be performance/memory heavy because it would need to create a lot of objects for each processed request.
- Some “global state” (thread-local…) storing the operation ID?
I am trying to not specify any concrete language since I consider this a general problem, more related to the design than the used language or technology.