Service Dependency Graph

Know your dependencies

Service 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:

  • they require usually quite sophisticated setup and infrastructure
  • they need your application to be active and working
  • and in the end, they do NOT cover all the documentation cases and are simply NOT descriptive enough: you can see data flows, but you don’t know what’s going on there, why this interaction is needed.

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.

Service dependencies in ServiceRegistry page of the app

Service dependencies in ServiceRegistry page of the app

BigPicture overview of all of the services

BigPicture overview of all of the services

Quick service information

Quick service information

Filter by service connections

Filter by service connections

Filter by the Owner

Filter by the Owner

Service dependency graph specification and agreements

  • 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
    

Very soon

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!