Microservices Starter Kit v1.0

(Updated Dec 18, 2024)

 


 

Microservice Manifesto


To ensure our distributed architecture is successful, we must ensure we have a set of guidelines that must be followed. Failure to do this will simply result in chaos and ultimate failure. What follows is a list of things that all service developers must ensure is taken into consideration when building or modifying any service.


1. Split code into smaller, more manageable components

  • Many smaller teams can work on different components contributing to the overall application ecosystem
  • Components can be built, tested and deployed independently to provide value much more quickly
  • Each component should use domain driven design
  • No component should have intimate knowledge of any other service

Benefits

  • A distributed microservice architecture forces us to think in small, atomic services/features
  • Each service lives in it's own source code repo and has it's own CI/CD pipelines
  • A single service has it's own concern. By following the "Separation of Concerns" principle will allow for build agility using existing building blocks


2. Employ a standard communication protocol

  • Ensure reliable, predictable and timely communication between components
  • Allow other systems/components to easily participate in/extend the features of an application or ecosystem

Benefits

  • Http and Json is widely accepted for REST Api services
  • An enterprise messaging platform (Kafka) enables very fast, highly available inter-service communication
  • An enterprise messaging platform (Kafka) enables easy integration with monolithic applications. Further it can enable the extension of a monolith by adding service features that respond to enterprise events
  • Message versioning (schemas) should be employed and validated to ensure message consistency


3. Enable simple adoption of new technology

  • There should be a path for new development, both new and re-engineering of old components
  • We should not be married to a language, framework or persistence mechanism

Benefits

  • Services are separated into their own code repositories and built using the language and data store most appropriate with the domain they are concerned with
  • New services can be built using different languages and data stores with no impact to other services


4. Reduce runtime environment complexity

  • Components should be quickly and easily deployable
  • Components should "just run". No more "works on my machine"

Benefits

  • Docker provides a build once, run anywhere approach to runtime environments
  • Each service has it's own CI/CD pipeline and a Docker container can be built and deployed within seconds of a code check-in
  • The only change between environments are environment variables. The bits are the same!
  • The service manages it's own data store and creates/updates the schema automatically using migrations
  • Testing is greatly reduced!


5. Enfore data quality and consistency

  • All data should be cleansed and verified prior to being persisted
  • Data should be segmented by domain/service
  • The type of data should determine the best mechanism for it's persistence

Benefits

  • Data reliability must be a core value
  • Data should be logically or physically partitioned by domain and owned by only one service
  • Database migrations must be used to ensure automated updates of schema and data
  • Historical and transactional data should be split
    • Ability to restrict access to historical or transactional
    • Tune transactional data differently than historical


6. Enforce high code quality as a core value

  • Use test automation and code analysis to ensure code confidence is high
  • Do not rely on manual testing!

Benefits

  • CI/CD (Continuous integration/deployment) pipelines can automate tasks for us:
    • Build code
    • Deploy to Docker container
    • Run unit, load, stress and e2e tests
    • Perform code quality analysis (SonarQube/SonarCloud)
    • Release docker container to an orchestration cluster (Kafka)


7. Ensure high availability and redundancy are core values

  • Build components/applications to work with many instances of themselves
  • Ensure fault tollerance and recovery

Benefits

  • Kubernetes allows the scaling of services based on individual demands
  • Kubernetes automatically manages the cluster and keeps it in a predefined state
  • Kubernetes does health checks and will kill and recreate unhealthy services. It will also ensure the desired number of services are always running
  • Kubernetes supports no downtime updates