Usually there are 2 solutions:
1. Define a new Request/Response type. When `inner.call()`, the information passed by the outer Service and the information obtained by this Service are combined into a new structure and passed down. The advantage of this is that it can ensure that the value exists, but the disadvantage is that you have to repeatedly define a new structure to store the merged information, and this kind of code will be very redundant.
2. Using a HashMap/TypeMap, the Map itself will be passed across Services, and each Service can inserte and delete values at will. The advantage of doing this is that it is really convenient and the code is clean; but the problem is that the existence of a specific kv depends entirely on the agreement. If the person in front forgets to set it, the later will panic when reading it(or bring unreasonable error handling logic which not expected to happen). This problem comes up many times in out RPC framework.
Here I use rust's type system to encode whether the key exists or not into the type. Adding or deleting a key means a type change, so that we can constrain the existence of a certain key, check at compile time, and say goodbye to this problem and the panic it caused.
To a certain extent, this sentence is re-fulfilled: If it compiles, it works. If you have the need to transfer information across Services, you will definitely like it.