Know your dependencies
If you would ask someone from the IT what is the one most hated part of the software development is - chances are high that you will be given an answer “Dependencies”. There are no developers or teams who like to be dependent on someone else’s product. Been dependent on another Service usually introduces moderate-to-high risks: cascading failures, delivery delays, complexity, security threats, breaking changes - you name it.
But in the modern world of SOA/microservices landscapes, you usually can not afford to not be dependent on some sort of another Service/Application. Dependencies are encouraged and are embraced by those architectures. They are the backbone of them. And this is for a good reason: dependencies are a necessary evil if you want to scale your IT landscape and in the end move fast and beat the competition. This means that if we apply those architectures then we should also embrace the reality and be ready to deal with negative sides of them. To mitigate the risks introduced by the dependencies it is really crucial to know your neighbors and the character of those interactions.
That is why Service360 introduces the concept of Service Dependency Graph. This is the standard that allows you to document all hard and soft service dependencies of your Application in the simple text format which is easy to read and maintain. And it also enables automated discovery of the Consumers of your own service!
Today in the industry there are multiple solutions offered which try to automatically determine whom your service communicates with. Different service mesh solutions offer some “sidecar” tracing options. And in some cases, they work pretty well. They can be really useful for real-time debugging of ongoing issue/outage for example.
But there is one fundamental flaw in them in case you want to use them for documentation: they are simply not designed for this:
Having in mind all those Service360 has designed a new document format with the working title “Service Dependency Graph”. It is a simple yet powerful text file format based on the amazing PlantUML tool. Chances are high that you already have it integrated into your IDE.
An example which is worth a thousand words:
@startuml
title HelloWorldService
node HelloWorldService {
}
node HelloProvider {
}
cloud ThirdPartyService {
}
HelloProvider ..> HelloWorldService : Consumes Hello events
HelloWorldService --> ThirdPartyService : Retrives World data
@enduml
As you see it is really easy to read and maintain such a file. It is stored in the same code repository as the Service code and it does not require any sophisticated tooling or special knowledge. Most of the IDEs have plugins that will happily draw the resulting graph because the “Service Dependency Graph” is a fully valid PlantUML file. We just add several additional agreements on top of the usual PlantUML format in order to make it a bit more specific.
From the first look, it might seem that there is one obvious downside to this solution compared to the automated options. Namely - you need to manually maintain it and there is a probability that it will go out of sync when developers will add new dependency and forget to update the file. And yes, indeed this might happen. This is the price for the simplicity of the solution. But from our experience with the usual nowadays pull/merge-request development flows this is quite a rare event and the risk of “out-of-sync” is completely overweighted by the benefits of the solution.
We encourage you to try organizing your service dependencies with deps.s360.puml files. Even if you not gonna use Service360 it will still pay off (while we’d love to see you onboard! :)) deps.s360.puml significantly improves the onboarding speed of the new team members and helps owners of the service to get faster back in the loop in case service was not in active development for a while.
Landscape properly documented via Service Dependency Graph will allow you to get a lot of unexpected insights about the platform.
Default filename recognised by Service360 platform is deps.s360.puml
. You can of course change it, but you would need to
adjust crawlers setup also.
Proper deps.s360.puml MUST have service name written in one liner
title
section. Service name MUST be the same as in service Passport.
Correct:
@startuml
title HelloWorldService
node HelloWorldService {
}
@enduml
Incorrect:
@startuml
node HelloWorldService {
}
@enduml
All nodes MUST have empty body {}
. Exception actor
node.
Reason: Reserved for forward-compatibility
Correct:
@startuml
title HelloWorldService
node HelloWorldService {
}
@enduml
Incorrect:
@startuml
node HelloWorldService
@enduml
Never add any consumers of your service (if your code is not
actively pushing data to them, but in that case they become your
dependency) even if you are aware of their existence.
Only add your service and dependencies of your service. The only
exception is the actor
node. Which depicts users interacting with
your service.
Reason: consumers come and go and you will probably never know the real state on your own. Real consumers will be inferred automatically based on deps.s360.puml files from all the services.
Correct:
@startuml
title HelloWorldService
node HelloWorldService {
}
@enduml
Incorrect:
@startuml
title HelloWorldService
node HelloWorldService {
}
node Consumer {
}
Consumer --> HelloWorldService
@enduml
For owned services use node
container. For external dependencies cloud
.
Correct:
@startuml
title HelloWorldService
node HelloWorldService {
}
cloud ThirdPartyService {
}
HelloWorldService --> ThirdPartyService
@enduml
Incorrect:
@startuml
title HelloWorldService
cloud HelloWorldService {
}
node ThirdPartyService {
}
HelloWorldService --> ThirdPartyService
@enduml
Data flow between services should be shown via arrows. Flow MUST be always shown from Caller to Callee in case of synchronous calls and from Producer to Consumer in case of asynchronous communication (events/messages/etc).
Synchronous calls MUST be shown using solid arrows -->
Asynchronous calls MUST be shown using dashed arrows ..>
Feel free to use -up->
, -down->
notations in case you want to.
Correct:
@startuml
title HelloWorldService
node HelloWorldService {
}
node HelloProvider {
}
cloud ThirdPartyService {
}
HelloProvider ..> HelloWorldService
HelloWorldService --> ThirdPartyService
@enduml
Incorrect:
@startuml
title HelloWorldService
node HelloWorldService {
}
node HelloProvider {
}
cloud ThirdPartyService {
}
HelloProvider <. HelloWorldService
HelloWorldService <-> ThirdPartyService
@enduml
You are encouraged to add one-liner descriptions to data flows so it will be easier for readers to digest your application data flows
Example:
@startuml
title HelloWorldService
node HelloWorldService {
}
node HelloProvider {
}
cloud ThirdPartyService {
}
HelloProvider ..> HelloWorldService : Consumes Hello events
HelloWorldService --> ThirdPartyService : Retrives World data
@enduml
In case your service name has spaces/dashes it MUST be properly
escaped using as
notation in the node name.
Example:
@startuml
title HelloWorldService
node "Hello-World Service" as HelloWorldService {
}
cloud ThirdPartyService {
}
HelloWorldService --> ThirdPartyService
@enduml
We are working hard with our alpha testers to make sure you will get the best in class product. Subscribe to our newsletter to stay informed about the progress and to receive an invitation to our beta test!