An ID for every transaction
A decoupled application may be depicted as a collection of autonomous services talking to each other via common protocols like HTTP, and relying on common standards like REST, asynchronous messaging, events, etc.
According to the Holographic Principle, we will say a decoupled application is holographic whenever all information any given service has of any other service in the application comes out of their contact surface, i.e., the place where their transaction contracts live.
One of the key consequences of this approach to implement decoupled applications is this:
Every Entity id must be solely local, only transaction ids (ephemeral ids) are shared
In other words, unique ids must be kept private inside the Service they belong to. In DDD terminology, we would say that Entity Ids must live strictly inside their bounded context, and only there.
This severe restriction in how decoupled Services may communicate is, in fact, an extremely powerful vector for providing freedom to our applications. Let’s look how.
Identify access, not resources
Mutual communication between services must be preceded by a negotiation on terms and conditions. Once an agreement is achieved, the whole list of agreed terms and conditions would be called a contract. These contracts are also going to be furnished with a unique identification.
Once a contract is considered valid by both Service Provider and Service Consumer, every new conversation initiated by either of them both would be uniquely identified by one transaction id (or, transid). This transid shall be shared throughout the conversation’s lifespan, to be ultimately expired and archived afterwards.
Under this schema, Transids carry plenty of information, specially in comparison to traditional URIs, which identify solely resources:
- The resource which is going to be accessed.
- The contract partners, in particular the Consumer willing to access that resource (since the Service providing the resource is always the same, of course).
- The actual transaction happening between both Services. This includes details like the actual date and time when the activity started, its lifespan, the price for that consumption, as well as the currency and other payment conditions, etc.
In other words, it should be clear now that:
Transaction Ids do not uniquely identify resources, but accesses to resources.
As I mentioned above, a key consequence of the Holographic Principle, and of the definition of the Transids, is that endpoints do not pinpoint resources anymore.
For instance, a Products Service exposing an endpoint to get a Product’s information (i.e., name, description, features, etc.), under a holographic architecture would expose different endpoints for every Service willing to access and get that Product’s information.
Since contract specifics’ are included (implicitly) in every hit to a given endpoint, now we can implement automated software to filter the access to our public resources depending on the identity of the Consumer wanting to access them, exactly like firewalls filter network traffic, just by yielding the data inscribed in the transid.
May transIds extend their lives further? Let’s say, for as long a period as safety measures advice, which actually is a topic I am elaborating in my next post; or, given the fact that every combination of one resource, one contractor, and one contract is unique, let their transId stay alive (meaning reachable) as long as the shortest of them all, the contract.
The answer is, of course! Actually lots of situations, and likely the cheapest ones, in implementation terms, fit this perdurable transIds definition.
For example, a Service A using a Picture Storage Service to store and read some pictures for, say, as much as 1000 times a week. It seems that the easiest way to implement this use case is to provide A with a perdurable transId for every picture; these permanent transIds would last either 1 week, or until A had (successfully) accessed them up to 1000 times in less than 1 week, and would be withdrawn afterwards.
However, there may be other alternatives to implement this use case. Just imagine that the Picture Storage Service is not the actual storage provider, but just a mediator, and it is actually proxying some other storage providers; depending on the fee and the actual usage of pictures, the Picture Storage Service shall be relocating them from one storage to another, in seek of better margins for itself, as it happens in other industries where specialisation is more mature than in software.
Production of transIds
The actual form of these transids is an issue every actual implementation must address. Alternatives do not stop at those defined by the RFC4122, which is the IETF standard most commonly used right now. Other examples might be Twitter’s Snowflake, the prefixed URNs in LinkedIn, etc.
Compliance of the Holographic Principle in a way which is not anaemic, i.e., a simple translation of internal ids to external ids, one by one, suggests the introduction of Transaction Ids (or transids for short) which do not identify resources, but the access to resources.
The condition every unique id must meet to be a valid transid is to identify one, and only one, combination of resource + consumer + contract. Regarding transids lifespan, they may:
- Be single use, meaning the transid is expended after one transaction is completed.
- Be perdurable, meaning the transid may last either a fixed period of time, say 1 week, or until a fixed condition is met, say 100 transactions in less than 1 week.
- Be permanent, meaning the transid is valid throughout the whole lifespan of the contract.
These access-oriented identifiers provide decoupled applications with a whole new ways to handle relationships between Services, which might be useful specially whenever the Service providers are independent from each other.
Photograph credit: https://pixabay.com/users/geralt-9301/