# Review No. 2 (Building microservices)

Published 2024-04-17

This page contains miscellaneous concepts about microservices briefly explained and design patterns.

# Single Responsibility Principle (SRP)

  • Each microservice should be responsible for a single business capability or domain.
  • A service focusing on a single responsibility is simpler to understand, test, and modify.
  • Services can be scaled independently
  • If a service fails, its impact is minimized
  • Teams can work on different services concurrently (development, test, deploy)
  • Easy to be reused

# API First

  • The API contract (definitions and behavior) is established upfront using tools like OpenAPI (Swagger)
  • The development of the backend and the frontend could be done in parallel
  • The clients could start implementing their modifications on their side

# Asynchronous Communication

  • Favor asynchronous communication for loosely coupled services

# One database per service

  • "One database per service" means that each microservice in a microservices architecture has its own dedicated database
  • Database resources can scale per service
  • Better security, adapted per service

# Using tokens (OAuth2, OpenID Connect) vs username/password

  • JWTs are a way to authorize a request, whereas username/password is a way to authenticate
  • The usage of tokens are more secure, flexible (could contains roles, etc)
  • For a traditional website, instead a JWT a cookie is used

# Secure Communication & Data

  • Secure the data in transit and data at rest

# Input Validation and Sanitization

  • Prevent common vulnerabilities like SQL injection attacks
  • Could be done in the frontend or on the server side

# Circuit Breakers

  • A Circuit Breaker is a design pattern used in microservices and distributed systems to prevent cascading failures across services
  • A circuit breaker typically has three states: CLOSED (Normal Operation), OPEN (Failure Detected), HALF-OPEN (Trial Period)
  • We can use Hystrix (Netflix), Resilience4j

# Horizontal Scalability

  • Design services to scale out (add instances) rather than scale up (increase instance size). For doing this, we can package services using Docker and deploy using Kubernetes or similar orchestrators.

# Backward compatibility

  • Ensure backward compatibility through API versioning to avoid breaking changes

# CI/CD Pipelines

  • Automate builds, tests, and deployments to enable continuous integration and continuous delivery

# Centralized Logging

  • is a system (Elasticsearch, Splunk, Graylog, etc) where logs from multiple sources/services are collected, aggregated, and stored in a single location

# Metrics and Alerts

  • Use tools like Prometheus and Grafana to monitor performance and set up alerts

# Tracing

  • Trace the flow of requests across services
  • Tools: Jaeger, Zipkin, OpenTelemetry

# Standardized Error Responses

  • Define a standard structure for error messages across services

# Correlation IDs

  • Use correlation IDs for tracking and debugging requests across multiple services

# Caching

  • Implement caching at appropriate layers (frontend, backend, database, in-memory caching)