{"id":19283562,"url":"https://github.com/ionutbalosin/ecommerce-app","last_synced_at":"2025-04-05T11:08:30.978Z","repository":{"id":60353525,"uuid":"534940370","full_name":"ionutbalosin/ecommerce-app","owner":"ionutbalosin","description":"eCommerce application is a platform where customers can find products, shop around using a cart, check out the products and initiate payments. It is used for the didactic purpose only, as a support project for my training.","archived":false,"fork":false,"pushed_at":"2024-10-08T11:52:05.000Z","size":2113,"stargazers_count":115,"open_issues_count":0,"forks_count":35,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-29T10:05:57.360Z","etag":null,"topics":["api-driven-development","asynchronous-logging","avro","caching","debezium","docker","event-driven","flywaydb","kafka","location-decoupling","microservices","openapi","postgresql","resilience","resilience4j","scalability","schema-first-approach","shared-nothing-database-approach","spring-boot","testcontainers"],"latest_commit_sha":null,"homepage":"https://ionutbalosin.com/training/designing-high-performance-scalable-resilient-applications","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ionutbalosin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE-HEADER.txt","code_of_conduct":"CODE-OF-CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-10T08:40:37.000Z","updated_at":"2025-02-28T11:24:16.000Z","dependencies_parsed_at":"2023-01-19T02:01:25.809Z","dependency_job_id":"46d50274-6d56-40b5-acac-a9107805f48b","html_url":"https://github.com/ionutbalosin/ecommerce-app","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionutbalosin%2Fecommerce-app","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionutbalosin%2Fecommerce-app/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionutbalosin%2Fecommerce-app/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ionutbalosin%2Fecommerce-app/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ionutbalosin","download_url":"https://codeload.github.com/ionutbalosin/ecommerce-app/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247325693,"owners_count":20920714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["api-driven-development","asynchronous-logging","avro","caching","debezium","docker","event-driven","flywaydb","kafka","location-decoupling","microservices","openapi","postgresql","resilience","resilience4j","scalability","schema-first-approach","shared-nothing-database-approach","spring-boot","testcontainers"],"created_at":"2024-11-09T21:33:43.212Z","updated_at":"2025-04-05T11:08:30.951Z","avatar_url":"https://github.com/ionutbalosin.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"eCommerce\" title=\"eCommerce\" src=\"assets/images/ecommerce_logo_320.png\"\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eeCommerce Application\u003c/h1\u003e\n\u003ch4 align=\"center\"\u003e⚡️ Architectural Empowerment: Applying Theory to Real-World Practice ⚡️\u003c/h4\u003e\n\n---\n\n\nThis repository provides practical examples and code snippets to help Java developers implement effective architectural concepts and design patterns with a main focus on performance, scalability, and resiliency as primary quality attributes.\n\nThese examples are designed to complement the curriculum of the 📚 [Designing High-Performance, Scalable, and Resilient Applications](https://ionutbalosin.com/training/designing-high-performance-scalable-resilient-applications) Course.\n\nIf you're looking to enhance your skills and design secure, high-performing applications, 🎓 [enroll](https://ionutbalosin.com/training/designing-high-performance-scalable-resilient-applications) now and master the principles of modern Java architecture!\n\nFor more resources and insights, feel free to visit my [website](https://ionutbalosin.com).\n\n---\n\n## Content\n\n- [Architectural Concepts](#architectural-concepts)\n- [Project Modules](#project-modules)\n- [Architectural Diagrams](#architectural-diagrams)\n  - [Software Architecture Diagram](#software-architecture-diagram)\n  - [Sequence Diagram](#sequence-diagram)\n  - [State Diagram](#state-diagram)\n- [Technology Stack](#technology-stack)\n- [SetUp](#setup)\n- [License](#license)\n\n## Architectural Concepts\n\nAmong the **architectural styles, design tactics, and patterns** demonstrated in this project:\n\n- Layered architecture, Hexagonal architecture, Event-driven microservices architecture\n- API-driven development approach\n- Schema-first development approach\n- Shared-nothing database approach\n- Schema registry\n- REST architectural style (e.g., RESTful APIs)\n- Scalability (e.g., horizontal scalability)\n- Location decoupling\n- Resiliency\n- Caching (e.g., local/embedded)\n- Asynchronous logging\n- Change data capture design pattern\n- Listen to yourself design pattern\n- Data transfer object enterprise application pattern\n\n## Project Modules\n\nThe purpose of this application is to have a platform where customers can find products, shop around using a cart, check out the products and initiate payments.\n\nBelow is a breakdown and description of each module in the current project.\n\nModule                                                  | Description\n------------------------------------------------------- |-------------------------------------------------------\n`Account service`                                       | Manages user data and exposes a GraphQL interface for retrieving accounts. It includes a prefilled user account for demonstration purposes.\n`Product service`                                       | Manages the product catalog and exposes an API to create, retrieve, update, and delete products. It includes a prefilled product catalog for quick setup.\n`Shopping cart service`                                 | Manages the user's shopping cart, exposing an API to create, retrieve, update, delete, and check out items in the cart.\n`Order service`                                         | Manages user orders and provides an API to retrieve historical orders and update them as needed.\n`Payment service`                                       | Processes payments for orders using an external payment system.\n`Shipping service`                                      | Simulates the shipment of successful orders to their destination after payment processing is completed.\n`Notification service`                                  | Logs all received events to the console for monitoring and debugging purposes.\n`Message schema library`                                | Contains AVRO message definitions used across services to ensure consistent data formats.\n\n## Architectural Diagrams\n\n### Software Architecture Diagram\n\n\u003cimg src=\"assets/diagrams/software-architecture-diagram.svg\"\u003e\n\n### Sequence Diagram\n\nEnd to end sequence diagram:\n\n```mermaid\nsequenceDiagram\nactor User\nUser-\u003e\u003eProduct Service: Get Products\nUser-\u003e\u003eShopping Cart Service: Save Products In Cart\nUser-\u003e\u003eShopping Cart Service: Checkout Cart Items\nShopping Cart Service-\u003e\u003eOrder Service: Publish Order Created Event\nOrder Service-\u003e\u003ePayment Service: Trigger Payment Command\ncritical Payment\n    Payment Service-\u003e\u003ePayment Gateway: Trigger Payment\n    Payment Gateway--\u003e\u003ePayment Service: Payment Status (e.g., APPROVED/FAILED)\nend\nPayment Service--\u003e\u003eOrder Service: Publish Payment Status Updated Event\nOrder Service-\u003e\u003eNotifications Service: Publish Payment Status Updated Event\nalt Payment APPROVED\nOrder Service-\u003e\u003eShipping Service: Trigger Shipping Command\nShipping Service--\u003e\u003eOrder Service: Publish Shipping Status Updated Event (e.g., IN_PROGRESS)\ncritical Shipping\n    Shipping Service-\u003e\u003eShipping Gateway: Trigger Shipping\n    Shipping Gateway-\u003e\u003eShipping Service: Shipping Status (e.g., COMPLETED/FAILED)\nend\nShipping Service--\u003e\u003eOrder Service: Publish Shipping Status Updated Event (e.g., COMPLETED/FAILED)\nOrder Service-\u003e\u003eNotifications Service: Publish Shipping Status Updated Event\nend\n```\n\n### State Diagram\n\nEvents state diagram:\n\n```mermaid\nstateDiagram-v2\n[*] --\u003e NEW\nNEW --\u003e PAYMENT_APPROVED\nNEW --\u003e PAYMENT_FAILED\nPAYMENT_FAILED --\u003e [*]\nPAYMENT_APPROVED --\u003e SHIPPING_IN_PROGRESS\nSHIPPING_IN_PROGRESS --\u003e SHIPPING_COMPLETED\nSHIPPING_IN_PROGRESS --\u003e SHIPPING_FAILED\nSHIPPING_FAILED --\u003e [*]\nSHIPPING_COMPLETED --\u003e [*]\n```\n\n## Technology Stack\n\nAmong the **technologies, frameworks, and libraries** included in this project:\n\n- [Spring Boot](https://spring.io/projects/spring-boot)\n- [JdbcTemplate](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/JdbcTemplate.html) (e.g., query, update, batch update)\n- [Caffeine](https://github.com/ben-manes/caffeine) caching\n- [Kafka](https://kafka.apache.org)\n- [PostgreSQL](https://www.postgresql.org)\n- [Flywaydb](https://flywaydb.org)\n- [Debezium](https://debezium.io/)\n- [Testcontainers](https://www.testcontainers.org)\n- [Resilience4j](https://github.com/resilience4j/resilience4j) (e.g., circuit breaker, bulkhead)\n- [Traefik](https://traefik.io) (i.e., HTTP reverse proxy and load balancer)\n- [AVRO](https://avro.apache.org) and [JSON](https://www.json.org) data format\n- [OpenAPI](https://www.openapis.org/) specification\n- [GraphQL](https://graphql.org/)\n- [Logback](https://logback.qos.ch/)\n- [Spotless](https://github.com/diffplug/spotless) code formatter\n- [Docker compose](https://docs.docker.com/compose/)\n- [ArchUnit](https://www.archunit.org/)\n\n## SetUp\n\nPlease make sure you have properly installed (and configured):\n\n- JDK 21 (i.e., latest LTS)\n- Docker\n- cURL\n- Postman\n\n### Compile, run tests, and package\n\n```\n./mvnw clean package\n```\n\n**Note:** Please start the Docker agent up front, otherwise, the tests fail.\n\n### Bootstrap all the services (and the dependencies) with Docker\n\n```\n./bootstrap.sh\n```\n\nTo check if all Docker containers are up and running execute the below command:\n\n```\ndocker ps -a\n```\n\n\u003e **Important:** On Windows using Docker compose v2 there is a known [limitation](https://github.com/docker/compose/issues/8530) while horizontally scaling a service by using port ranges like \"8080-8081:80\".\n\u003e \n\u003e At the moment, the workaround is to simply copy-paste (multiple times) the same service inside the Docker compose YAML file and explicitly assign different ports to each.\n\n### Register the PostgreSQL connector\n\nThe PostgreSQL connector is used to monitor and record the row-level changes in the PostgreSQL database schema.\n\n**Note:** please make sure all services (e.g., PostgreSQL and Kafka) are up and running before registering the connector \n\n```\n./debezium-register-postgres.sh\n```\n\nOnce the PostgreSQL connector is successfully registered, it reads the database log and produces events for row-level INSERT, UPDATE, and DELETE operations, emitting such events to the Kafka topic (in this case to the `ecommerce-product-cdc-topic`).\n\n### Services overview via UI \n\nOpen a browser and navigate to http://localhost:26060 to access the **Traefik UI** (it shows endpoints, routes, services, etc.). \n\nOpen a browser and navigate to http://localhost:19000 to access the **Kafdrop UI** (it shows topics, partitions, consumers, messages, etc.).\n\nOpen a browser and navigate to http://localhost:18080 to access the **Debezium UI** (it shows the PostgreSQL connector).\n\nOpen a browser and navigate to http://localhost:55080/graphiql?path=/graphql to access the **GraphiQL** in-browser tool for writing, validating, and testing GraphQL `account-service` queries.\n\n### Local tests with Postman\n\n- open Postman\n- import the provided API collections, corresponding to each project, as follows:\n  - `./ecommerce-app/order-service/postman`\n  - `./ecommerce-app/product-service/postman`\n  - `./ecommerce-app/shopping-cart-service/postman`\n- to simulate a basic test scenario please trigger the below requests (in this sequence):\n\n```\nGET http://localhost:{{port}}/products\n```\n```\nPOST http://localhost:{{port}}/cart/{{userId}}/items\n```\n```\nPOST http://localhost:{{port}}/cart/{{userId}}/checkout\n```\n```\nGET http://localhost:{{port}}/orders/{{userId}}/history\n```\n\n**Note:** the ports (i.e., service port or Traefik load balancer port) are already configured as variables in the Postman collections\n\n### TODOs\n\nA few, optional, TODOs for further enhancements might be:\n\n- implement a scheduler to reply unprocessed/failed events\n- implement API pagination\n- implement database bulk updates for the remaining APIs\n\n## License\n\n\nThis project is licensed under the MIT License.\n\nPlease see the [LICENSE](LICENSE.md) file for full license.\n\n```\n/**\n*  eCommerce Application\n*\n*  Copyright (c) 2022 - 2024 Ionut Balosin\n*  Website: www.ionutbalosin.com\n*  X: @ionutbalosin | LinkedIn: ionutbalosin | Mastodon: ionutbalosin@mastodon.social\n*\n*\n*  MIT License\n*\n*  Permission is hereby granted, free of charge, to any person obtaining a copy\n*  of this software and associated documentation files (the \"Software\"), to deal\n*  in the Software without restriction, including without limitation the rights\n*  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n*  copies of the Software, and to permit persons to whom the Software is\n*  furnished to do so, subject to the following conditions:\n*\n*  The above copyright notice and this permission notice shall be included in all\n*  copies or substantial portions of the Software.\n*\n*  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n*  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n*  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n*  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n*  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\n*  SOFTWARE.\n*\n*/\n```","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fionutbalosin%2Fecommerce-app","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fionutbalosin%2Fecommerce-app","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fionutbalosin%2Fecommerce-app/lists"}