A repo that contains bootstrapping code and reference implementations for developing a microservice.
Built in Java.
Project configuration:
- README
- .gitignore
- Docs + ADRs (MkDocs + Markdown)
- Automated Dependency Updates (Renovate)
- Automated Code Refactoring (OpenRewrite)
- HTTP API Specification (OpenAPI)
- Async API Specification (AsyncAPI)
- Dependency Management (Maven + BOMs)
Application configuration:
- Dependency Injection and Application Mgmt (Spring Boot & Starters)
- Unit Testing (JUnit)
- Logging Config (Slf4j & Logback)
- Tracing configuration (OpenTelemetry Java Agent for zero-code instrumentation, OpenTelemetry annotations for custom instrumentation)
- Metrics configuration (Micrometer + Prometheus Registry/Endpoint)
Build / CI:
- Test & Build automation (Maven, GitHub Actions)
- Uses reusable workflows for ease of CI maintenance.
- Java Project + Container image specific build process:
- Lint/Scan Java code (PMD, Modernizer, SpotBugs)
- Reformat Java code
- Testing (Maven Surefire plugin)
- Automated publishing of Contract Testing Contracts and Results (PACT Broker, GitHub Actions)
- Packaging JAR (Maven Compiler plugin, Spring Boot Maven plugin)
- Packaging and pushing a container image (Jib Maven plugin)
Deployment / CD:
- Kubernetes resources (Kustomize)
- Spread pods (Pod Anti-affinity)
- Auto-scaling (HPA)
- Pod security (SecurityContext)
- Expected that an external CD system would deploy to Kubernetes (e.g. Argo CD)
- Expected that this configuration would actually be in a deployment repository.
Infrastructure as Code:
- Databases - Terraform, or Self-hosted Kubernetes-operated:
- SQL = PostgreSQL / CloudNativePG / MySQL / GCP CloudSQL / AWS RDS / AWS Aurora / Azure Database for PostgreSQL
- Key-Value Memory Store (Caching) = Redis / Memcache / Valkey / GCP Memorystore / AWS ElasticCache / Azure Cache
- High-available Key-Value (key-value / document / analytical) = GCP BigTable / AWS DynamoDB / Azure Cosmos DB
- Document-oriented = DocumentDB / MongoDB / GCP Datastore / GCP Firestore / AWS DocumentDB / Azure DocumentDB
- Message Bus, Queue, PubSub, Topics & Subscriptions - Terraform, or Self-hosted Kubernetes-operated:
- RabbitMQ
- Google Pub/Sub
- AWS Simple Queue Service (SQS)
- Azure Service Bus
- Blob Storage (also for Data Lakes) - Terraform, or Self-hosted Kubernetes-operated:
- PersistentVolumes / Disks
- Network Attached Storage (NAS) cluster, accessed via SFTP / Samba
- GCP Storage (buckets)
- AWS Simple Storage Service (S3)
- Azure Storage
- Search Engines (offloading from microservice) - Terraform, or Self-hosted Kubernetes-operated:
- ElasticSearch
- Apache Solr
- PostgreSQL (Full Text Search)
- GCP Vertex AI Search
- AWS CloudSearch
- Azure Cognitive Search
- Rudimentary applying of Terraform (GitHub Actions)
- Expected that an external CD system would apply Terraform (e.g. Atlantis).
- Expected that an external CD system would apply Kubernetes installations (e.g. ArgoCD + Operators / Helm Charts).
- Expected that this configuration would actually be in a deployment repository.
Reference implementation examples (production):
- Application Structure Example (
app.structure.account)- Reasonably decoupled layers/components
- Domain-driven
- Scoped explicit exception handling
- Simple reusable model, mapping done in layers (if needed)
- Dependency Injection used
- No implementation details (as implementations covered in other reference implementations)
- HTTP Endpoint
- Front Controller pattern
- Authorization checks
- Versioning
- HTTP POST Idempotency
- Offset Pagination
- Cursor Pagination
- Caching (where appropriate)
- Server Sent Events
- Feature flag for toggling / releasing endpoints
- Business Logic
- Modelling
- Service Layer pattern
- Transactions
- Concurrency / Parallelisation of doing work / collecting data (Virtual Threads)
- Repository pattern
- JDBC
- Not Jakarta Persistence API (JPA) / ORMs
- External communication components
- Event Publisher (simple & with Outbox pattern, with CloudEvents (inc. idempotency))
- Event Subscriber with resubscribe (simple & with Inbox pattern, with CloudEvents (inc. idempotency & feature flag for pausing / totally blocking / releasing processing functionality))
- HTTP Client (simple & resilient & streamed-response)
- TCP Socket Send / Receive
- Blob Storage Client (Google Storage / SFTP Connection)
- Resiliency patterns (with Resilience4J and/or alternatives)
- Bulkhead
- Cache (Simple)
- Cache (Offline API)
- Circuit Breaker
- Rate Limiter
- Retry
- Timeout / Time Limiter
- Telemetry
- Tracing instrumentation (OpenTelemetry Annotations)
- Metrics instrumentation (Micrometer or OpenTelemetry)
- Logging instrumentation (SLF4J and Logback)
- Profiling instrumentation (Built-in, accessible via JMX for usage with VisualVM, eventually OpenTelemetry)
Reference implementations (testing):
- Provider Contract Testing the Controller (PACT)
- Consumer Contract Testing the HTTP Client (PACT)
- Integration Testing the Repository (in-memory DB)
- Integration Testing the Event Publisher (Testcontainers)
- Integration Testing the Event Subscriber (Testcontainers)
Docs are found in /docs.
Uses mkdocs to handle documentation, which requires Python (hence the requirements.txt).
Run docs locally by doing:
# Before running the following, I recommend being in a Python Virtual Environment.
pip install -r requirements.txt
mkdocs serveThen open at localhost:8000.
mvn spring-boot:run- Endpoints accessible on localhost:8080.
- Management endpoints on: localhost:8081.
When being used for templating, remember to set the following in your new repository:
- Rename all instances of
init-microservicewith your application name. - Refactor the package structure of
init.microserviceto be what you need. - For GitHub Actions, use the Workflow Permissions: "Read and write permissions".
- Remove/Refactor the infrastructure to ensure it is scoped to the new project (i.e. backend config bucket with a prefix).
- Remove/Refactor the PACT tests to ensure they don't interfere with the
init-microservicePACT tests results (or any others).