{"id":31765742,"url":"https://github.com/ashrithvm/cloud-cart-sharp","last_synced_at":"2026-07-28T19:31:12.312Z","repository":{"id":313685621,"uuid":"1052280293","full_name":"ashrithvm/cloud-cart-sharp","owner":"ashrithvm","description":null,"archived":false,"fork":false,"pushed_at":"2025-09-07T19:21:59.000Z","size":483,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-10-10T00:27:58.062Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ashrithvm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-09-07T19:10:58.000Z","updated_at":"2025-09-07T19:22:02.000Z","dependencies_parsed_at":"2025-09-07T21:19:35.878Z","dependency_job_id":"6932dcc2-9d42-41bf-94a0-8ad9d647b0e9","html_url":"https://github.com/ashrithvm/cloud-cart-sharp","commit_stats":null,"previous_names":["ashrithvm/cloud-cart-sharp"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ashrithvm/cloud-cart-sharp","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashrithvm%2Fcloud-cart-sharp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashrithvm%2Fcloud-cart-sharp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashrithvm%2Fcloud-cart-sharp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashrithvm%2Fcloud-cart-sharp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ashrithvm","download_url":"https://codeload.github.com/ashrithvm/cloud-cart-sharp/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ashrithvm%2Fcloud-cart-sharp/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":36006421,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-28T02:00:06.341Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-10-10T00:26:07.194Z","updated_at":"2026-07-28T19:31:12.306Z","avatar_url":"https://github.com/ashrithvm.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Cloud Cart\n\nThis is a shopping application designed with microservices architecture. My main goal is to learn about\ndevops and microservices, but I am also improving the domain part as much as possible. The project is about recording\ntransactions of a shopping application.\n\u003ca href=\".docs/run-options.md\"\u003eCheck to see how to run.\u003ca/\u003e\n\n## Architecture\n### Development\n![development](./image.png)\n\nIn development mode, microservices are running as separate processes on your computer. The API Gateway, database,\nRabbitMQ, Redis and Keycloak run\nas Docker containers. Since all microservices run on the same device, they should expose a different port. The\ncommunication between client\nand microservices is done through the API Gateway. Databases are in the same instance for the sake of simplicity in this\nenvironment.\n\n### Test\n\n![test](./image2.png)\n\nIn test mode, the whole application lives in a Kubernetes cluster which runs on your computer. Microservices, API\nGateway, databases, Redis, RabbitMQ and Keycloak now\nrun as Kubernetes deployments or statefulsets.\n\nThe communication between components is done through services (another Kubernetes\ncomponent, shown as triangles). In terms of scalability, microservices can have more than one instances, called\nreplicas. With Kubernetes, we can easily define\na new replica for a microservice if we need more instances to distribute upcoming traffic. For example account service\ncan have 1 replica and inventory\nservice can have 3 replicas. Distributing the traffic across the replicas is also done with services.\n\n### Production\n\n![prod](./image3.png)\n\nProduction environment is very similar to the test environment. However, the cluster is on remote servers now, just like\na real world\nproduction environment.\nI used AWS as a cloud provider for this environment. I also provisioned the databases on AWS, not inside Kubernetes. \u003cb\u003e\nPlease note that I'm not keeping the production environment up\n7/24, that would be very costly.\u003c/b\u003e\nLet's explain each component shown in the diagram one by one:\n\n- **Route 53**: This service is responsible for managing DNS in AWS. When the user types a url, it is resolved to the url of the ALB.\n  This process is done by Route 53.\n- **ALB**: The ingress resource defined for the K8S cluster is converted to an ALB (Application Load Balancer). AWS\n  reads the routing rules, services and the SSL configuration we defined in the ingress file and applies all of them in\n  the ALB which will route the traffic to the cluster. Each ingress defined in K8S has a correspondence in ALB.\n- **Target Groups**: These are subcomponents of the ALB. A target group is solely responsible for load balancing. For\n  example if a deployment has 3 replicas, it's the target groups responsibility to distribute\n  the traffic across the replicas. Each Kubernetes service\n  defined in the ingress file is converted to a target group in ALB.\n- **Private Subnet**: Giving nodes (servers) of the cluster public IP addresses poses a security risk. Anyone could see\n  the nodes and\n  try to exploit them. To prevent this, all servers are inside a private network, making them invisible from the outside\n  world.\n- **NAT Gateway**: Since our nodes don't have a public IP address, they can't directly access to the internet. We need a\n  server that does a network address translation (NAT), making our nodes access the internet in a more secure way.\n- **Public Subnet**: This is where servers are publicly visible. We need ALB to be public to access our application. We\n  also need NAT Gateway to be public to give internet access to our nodes. The security of these two are handled by AWS.\n- **Master Nodes**: These are responsible for managing worker nodes. We don't really have any control over master nodes,\n  they are fully managed by AWS.\n- **Worker Nodes**: These are where our applications run. The Kubernetes cluster drawn in the test environment is\n  spanned across\n  the worker nodes here.\n- **CloudFormation**: The whole infrastructure (nodes, subnets, ALB, NAT gateway etc.) is built on CloudFormation. This\n  service\n  provides a way to manage AWS resources easier using declarative approaches.\n- **RDS**: All databases are provisioned by using RDS (Relational Database Service). The engine is still PostgreSQL but\n  backups,\n  monitoring, high availability and disaster recovery is much easier. When the environment is going up, the databases\n  are\n  provisioned from previous snapshots, so the data is never lost.\n\n## Topics\n- \u003ca href=\".docs/run-options.md\"\u003eRun options\u003ca/\u003e\n- \u003ca href=\".docs/hexagonal-architecture.md\"\u003eHexagonal Architecture\u003ca/\u003e\n- \u003ca href=\".docs/syncronous-communication.md\"\u003eSynchronous Communication\u003ca/\u003e\n- \u003ca href=\".docs/circuit-breaking.md\"\u003eCircuit Breaking\u003ca/\u003e\n- \u003ca href=\".docs/asyncronous-communication.md\"\u003eAsynchronous Communication\u003ca/\u003e\n- \u003ca href=\".docs/api-gateway.md\"\u003eAPI Gateway\u003ca/\u003e\n- \u003ca href=\".docs/authentication-authorization.md\"\u003eAuthentication \u0026 Authorization\u003ca/\u003e\n- \u003ca href=\".docs/horizontal-scaling.md\"\u003eHorizontal Scaling\u003ca/\u003e\n- \u003ca href=\".docs/load-balancing.md\"\u003eLoad Balancing\u003ca/\u003e\n- \u003ca href=\".docs/entity-relations.md\"\u003eEntity Relations\u003ca/\u003e\n- \u003ca href=\".docs/caching.md\"\u003eCaching\u003ca/\u003e\n- \u003ca href=\".docs/shared-module.md\"\u003eShared Module\u003ca/\u003e\n- \u003ca href=\".docs/infrastructure-as-code.md\"\u003eInfrastructure as Code\u003ca/\u003e\n- \u003ca href=\".docs/gitops.md\"\u003eGitOps\u003ca/\u003e\n- \u003ca href=\".docs/zero-2-prod.md\"\u003eFrom Zero to Prod In Minutes\u003ca/\u003e\n- \u003ca href=\".docs/testing.md\"\u003eTesting\u003ca/\u003e\n\n## Roadmap\n\n- Domain enrichment (add more features)\n- Data enrichment (add millions of records for prod environment)\n- Monitoring (LGTM Stack)\n- ~~AI assistant (agent to explain docs)~~\n- Maybe it's time to create a frontend ??\n- Apply CQRS in one of the microservices\n- Migration from RabbitMQ to Kafka\n- Microservice with different framework\n- Microservice with different programming language\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashrithvm%2Fcloud-cart-sharp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fashrithvm%2Fcloud-cart-sharp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fashrithvm%2Fcloud-cart-sharp/lists"}