{"id":27414378,"url":"https://github.com/yeahbutstill/food-ordering-system","last_synced_at":"2026-04-07T08:32:04.004Z","repository":{"id":174519505,"uuid":"652354378","full_name":"yeahbutstill/food-ordering-system","owner":"yeahbutstill","description":"Example Hexagonal with DDD","archived":false,"fork":false,"pushed_at":"2023-06-22T01:33:24.000Z","size":102422,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-14T08:45:27.834Z","etag":null,"topics":["ddd","docker","hexagonal-architecture","java","k8s","kafka","postgresql","saga"],"latest_commit_sha":null,"homepage":"","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/yeahbutstill.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}},"created_at":"2023-06-11T21:58:28.000Z","updated_at":"2024-11-15T11:40:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"efb744f5-83f1-4308-bf33-78558e8cd61f","html_url":"https://github.com/yeahbutstill/food-ordering-system","commit_stats":null,"previous_names":["yeahbutstill/food-ordering-system"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/yeahbutstill/food-ordering-system","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeahbutstill%2Ffood-ordering-system","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeahbutstill%2Ffood-ordering-system/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeahbutstill%2Ffood-ordering-system/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeahbutstill%2Ffood-ordering-system/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yeahbutstill","download_url":"https://codeload.github.com/yeahbutstill/food-ordering-system/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yeahbutstill%2Ffood-ordering-system/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31506562,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["ddd","docker","hexagonal-architecture","java","k8s","kafka","postgresql","saga"],"created_at":"2025-04-14T08:24:51.699Z","updated_at":"2026-04-07T08:32:03.998Z","avatar_url":"https://github.com/yeahbutstill.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# food-ordering-system\n\n## Run Postgres\n```shell\ndocker run --rm \\\n--name food-ordering-system-db \\\n-e POSTGRES_DB=postgres \\\n-e POSTGRES_USER=postgres \\\n-e POSTGRES_PASSWORD=admin \\\n-e PGDATA=/var/lib/postgresql/data/pgdata \\\n-v \"$PWD/postgres-data:/var/lib/postgresql/data\" \\\n-p 5432:5432 \\\npostgres:15\n```\n\n## Create schema and Insert Data\n```text\n- order-service/order-container/src/main/resources/restaurant-schema.sql\n- order-service/order-container/src/main/resources/restaurant-data.sql\n```\n\n## Run Zookeper\n```shell\n# goto directory\ncd infrastructure/docker-compose\n# run\ndocker compose -f common.yml -f zookeeper.yml up\n# to stop\ndocker compose -f common.yml -f zookeeper.yml down\n# open new terminal test\necho ruok | nc localhost 2181\n```\nhttps://zookeeper.apache.org/doc/r3.1.2/zookeeperAdmin.html#sc_zkCommands\n\n## Run Kafka Cluster\n```shell\n# cd infrastructure/docker-compose\ndocker compose -f common.yml -f kafka_cluster.yml up\n# to stop\ndocker compose -f common.yml -f kafka_cluster.yml down\n# open new terminal and run this for create topic\ndocker compose -f common.yml -f init_kafka.yml up\n```\n\n## Build\n```shell\nmvn clean install\n```\n\n## Let's confirm this by opening the kafka manager user interface\n```http request\nlocalhost:9000\n```\n\n## Add Cluster\n```text\nlocalhost:9000\nname cluster: food-ordering-system-cluster\nhost: zookeeper:2128\n```\nAnd save. Now, if I list the clusters, I will see three brokers and a topic created using init-kafka.yml docker compose file\n\n## Check data in topic using kafkacat\n```shell\nkcat -C -b localhost:19092 -t payment-request\n```\n\n##### ingat saat anda menggunakan pemetaan volume, anda harus terlebih dahulu memulai Zookeeper dan kemudian memulai Cluster Kafka, karena kafka cluster memeriksa kesehatan Zookeeper saat startup dan gagal jika tidak sehat\n\n## Note\n- The main target of all these architectures is to isolate the domain layer to develop, test, manage and deploy it separately.\n- SAGA is used to create long running distributed transactions across services.\n- Input ports are implemented in the domain layer but is not the adapter itself, whilst output ports are implemented with secondary adapters, with infrastructure modules.\n- DIP(dependency inversion principle) leads to loosely coupled systems and an independent domain layer, by inverting any runtime dependency.\n- Aggregate: Group of entities that are logically related. \n- Aggregate root: Root entity to keep the aggregate in a consistent state. \n- Entity: Core domain objects. \n- Value object: Used to bring context to the value. \n- Domain Event: Used to decouple the different domains. It will notify the other domains based on result of business logic.\n- Value objects are immutable and only holds data, so identifier is not important for them. That means 2 value objects with same data, but different id’s considered to be the same value object.\n- Entity classes do not have to be immutable. In fact they have state changes methods to run during business logic\n- Application service should be the first contact point to outside of domain, and it will forward the call to the domain service and entities to complete a business logic.\n- TransactionalEventListener is a spring annotation that listens an event that is fired from a transactional method. And it only process the event if the transactional operation is completed successfully.\n- Kafka provides a replication factor. It replicates the data on different brokers on different servers. So even if one of the brokers is down, the data will still be available on other nodes.\n- KafkaTemplate is a spring component that wraps a Kafka Producer and provides method to easily produce data on kafka. \n- To create a Kafka Consumer with spring, using a KafkaListener annotation on a simple method is enough. \n- If my kafka topic has n partitions, I cannot use more than n threads to consume the data on topics. \n- Kafka Consumer has a max poll records property that limits the number of records returned for a single poll.\n- ControllerAdvice: Used to catch exceptions application wide. \n- RestController: Used to create a rest controller with path mapping, and accept type. \n- RequestBody: Used to mark a java class as a request body in the rest request. Spring will map the json body into this class by setting the values automatically. \n- PostMapping: Used to create a method that will serve to a http post request.\n- Entities and domain services has the business logic. \n- Domain events should be created in entity or domain services after related business logic is completed. \n- Application services are the first initial contact point to the outside of domain. \n- Domain events should be fired after the related business logic is persisted.\n- It is used to create a chain of ACID transactions across services. \n- It is used on distributed environments that multiple services communicate.\n- SAGA is difficult to debug as multiple microservices are involved. So it it crucial to have a robust tracing implementations, with trace and span id. \n- As a result of compensating transactions, when user sees a change, in the second look after some time, \n- It is used to add a strong consistency between local acid transactions and event publishing operation. \n- It relies on keeping the domain events in local database to be published later. \n- Two ways to implement publishing part are Pulling the outbox table and CDC(Change Data Capture). \n- It makes SAGA pattern consistent when combined with SAGA.\n- CQRS is used to separate write and read parts with eventual consistency\n- Pod is the smallest deployable unit. \n- A pod can consist of one or more containers. \n- Services are used to expose deployment through NodePort or Loadbalancer.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyeahbutstill%2Ffood-ordering-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyeahbutstill%2Ffood-ordering-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyeahbutstill%2Ffood-ordering-system/lists"}