{"id":14987700,"url":"https://github.com/mikhailgulkin/cleangolangorderapp","last_synced_at":"2025-04-12T00:17:09.748Z","repository":{"id":176642373,"uuid":"658446860","full_name":"MikhailGulkin/CleanGolangOrderApp","owner":"MikhailGulkin","description":null,"archived":false,"fork":false,"pushed_at":"2023-10-02T22:16:41.000Z","size":7576,"stargazers_count":28,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-04-12T00:16:59.275Z","etag":null,"topics":["architecture","clean-architecture","cqrs","cron","crud","ddd","ddd-architecture","gin-gonic","go","golang","rabbitmq","saga","sql"],"latest_commit_sha":null,"homepage":"","language":"Go","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/MikhailGulkin.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}},"created_at":"2023-06-25T19:07:55.000Z","updated_at":"2025-03-29T16:07:34.000Z","dependencies_parsed_at":"2025-02-20T10:42:19.657Z","dependency_job_id":null,"html_url":"https://github.com/MikhailGulkin/CleanGolangOrderApp","commit_stats":null,"previous_names":["mikhailgulkin/simplegoorderapp","mikhailgulkin/cleangolangorderapp"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikhailGulkin%2FCleanGolangOrderApp","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikhailGulkin%2FCleanGolangOrderApp/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikhailGulkin%2FCleanGolangOrderApp/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/MikhailGulkin%2FCleanGolangOrderApp/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/MikhailGulkin","download_url":"https://codeload.github.com/MikhailGulkin/CleanGolangOrderApp/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248497817,"owners_count":21113984,"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":["architecture","clean-architecture","cqrs","cron","crud","ddd","ddd-architecture","gin-gonic","go","golang","rabbitmq","saga","sql"],"created_at":"2024-09-24T14:15:13.916Z","updated_at":"2025-04-12T00:17:09.725Z","avatar_url":"https://github.com/MikhailGulkin.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Order Service\n\nOrder Service is a simple Web API.\n\n## Principles and patterns that I use:\n\n- Clean Architecture\n- Experiments with DDD\n- CQRS (All but one method use half of the CQRS; `GetAllOrdersByUserID` uses the cache)\n- Outbox Pattern\n- Saga Pattern(Choreography-based)\n- Mediator with Query and Command Bus(`MediatR` inspired)\n\nTo use Saga pattern need external `CustomerService` or you can simulate events with RabbitMQ admin panel\n## Endpoints\n#### GET /healthcheck/\n```bash\ncurl -X \"GET\" \"http://localhost:8000/healthcheck/\"\n```\n```json\n{\"status\": \"OK\"}\n```\nTo create order need some product, address and client.\n#### POST /products/\n```bash\ncurl -X \"POST\" \\\n  \"http://localhost/api/v1/products/\" \\\n  -d '{\n    \"productID\": \"ec14f9be-44e3-4ec0-97d3-47fdac6c55c9\",\n    \"price\": 100,\n    \"discount\": 10,\n    \"Description\": \"string\",\n    \"Name\": \"string\"\n}`\n```\n`Status 204 No Content`\n\n#### POST /address/\n```bash\ncurl -X \"POST\" \\\n  \"http://localhost/api/v1/address/\" \\\n  -d '{\n    \"addressID\": \"7b2b575e-65e7-427c-bb1b-1fe609fc1f6b\",\n    \"buildingNumber\": 44,\n    \"streetName\": \"string\",\n    \"city\": \"string\",\n    \"country\": \"string\"\n}`\n```\n`Status 204 No Content`\n\n#### POST /users/\n```bash\ncurl -X \"POST\" \\\n  \"http://localhost/api/v1/users/\" \\\n  -d '{\n    \"userID\": \"4b2b575e-65e7-427c-bb1b-1fe609fc1f6b\",\n    \"username\": \"string\",\n    \"addressID\": \"7b2b575e-65e7-427c-bb1b-1fe609fc1f6b\"\n}`\n```\n`Status 204 No Content`\n\n#### POST /orders/\n```bash\ncurl -X \"POST\" \\\n  \"http://localhost/api/v1/orders/\" \\\n  -d '{\n    \"orderID\": \"1b2b434e-44e8-424c-bb1b-1fe609fc1f7d\",\n    \"paymentMethod\": \"string\",\n    \"productsIds\": [\"ec14f9be-44e3-4ec0-97d3-47fdac6c55c9\"],\n    \"userID\": \"4b2b575e-65e7-427c-bb1b-1fe609fc1f6b\",\n    \"deliveryAddress\": \"7b2b575e-65e7-427c-bb1b-1fe609fc1f6b\"\n}`\n```\nAfter creating an order, need to imitate a response from a third-party service\n#### RabbitMQ\n- CustomerSaga Queue Payload\n```bash\n{\n    \"orderID\": \"1b2b434e-44e8-424c-bb1b-1fe609fc1f7d\",\n    \"orderType\": \"Approved\"\n}\n```\nAfter publish payload can get orders:\n#### GET /orders/\n- From DB\n```bash\ncurl -X \"GET\" \"http://localhost:8000/api/v1/orders?limit=10\u0026order=asc\"\n```\n```json\n{\n    \"orders\": [\n        {\n            \"orderStatus\": \"New\",\n            \"paymentMethod\": \"Online\",\n            \"client\": {\n                \"ClientID\": \"4b2b575e-65e7-427c-bb1b-1fe609fc1f6b\",\n                \"ClientName\": \"test\"\n            },\n            \"address\": \"Russia, Moscow, Pushkina, 44\",\n            \"OrderID\": \"1b2b434e-44e8-424c-bb1b-1fe609fc1f7d\",\n            \"serialNumber\": 1,\n            \"products\": [\n                {\n                    \"productID\": \"ec14f9be-44e3-4ec0-97d3-47fdac6c55c9\",\n                    \"name\": \"he3444443h1\",\n                    \"actualPrice\": 90\n                }\n            ],\n            \"createdAt\": \"2023-07-23T00:27:52.641012+03:00\",\n            \"totalPrice\": 90\n        }\n    ],\n    \"count\": 1,\n    \"limit\": 10,\n    \"order\": \"asc\"\n}\n```\n\n#### GET /orders/user/:id\n- From Redis Cache\n```bash\ncurl -X \"GET\" \"http://localhost:8000/api/v1/orders/user/4b2b575e-65e7-427c-bb1b-1fe609fc1f6b?limit=10\u0026order=desc\"\n```\n```json\n{\n    \"orders\": [\n        {\n            \"orderStatus\": \"New\",\n            \"paymentMethod\": \"Online\",\n            \"client\": {\n                \"ClientID\": \"4b2b575e-65e7-427c-bb1b-1fe609fc1f6b\",\n                \"ClientName\": \"test\"\n            },\n            \"address\": \"Russia, Moscow, Pushkina, 44\",\n            \"OrderID\": \"1b2b434e-44e8-424c-bb1b-1fe609fc1f7d\",\n            \"serialNumber\": 1,\n            \"products\": [\n                {\n                    \"productID\": \"ec14f9be-44e3-4ec0-97d3-47fdac6c55c9\",\n                    \"name\": \"he3444443h1\",\n                    \"actualPrice\": 90\n                }\n            ],\n            \"createdAt\": \"2023-07-23T00:32:00.414866435+03:00\",\n            \"totalPrice\": 90\n        }\n    ],\n    \"count\": 1,\n    \"limit\": 10,\n    \"order\": \"desc\"\n}\n```\n## Dependencies\n### Infrastructure\n- [Postgres](https://www.postgresql.org/docs/current/index.html) — Database\n- [RabbitMQ](https://www.rabbitmq.com/) — The queue used to publish and handle events\n- [Redis](https://redis.io/) — For Query cache\n- [Docker](https://docs.docker.com/) — For deployment\n\n### Grafana stack\n- [Grafana](https://grafana.com/docs/grafana/latest/) — Web view for logs and prometheus info\n- [Loki](https://grafana.com/docs/loki/latest/) — A platform to store and query logs\n- [Vector.dev](https://vector.dev) — A tool to collect logs and send them to Loki\n- [Prometheus](https://prometheus.io/) — A tool to alerting series info\n\n### Golang libs\n- [Gin](https://gin-gonic.com/) - Web framework\n- [Gorm](https://gorm.io/index.html) - ORM for working with database \n- [go-redis](https://redis.uptrace.dev/) - Cache database for query request\n- [cron](https://github.com/robfig/cron) - To implement relay from Outbox pattern\n- [fx](https://uber-go.github.io/fx/) - A dependency injection tool for easy initialization and delivery of dependencies\n- [zap](https://pkg.go.dev/go.uber.org/zap) - For better logging config\n- [amqp091-go](https://github.com/rabbitmq/amqp091-go) - For working with RabbitMQ\n\n### Setup\nThe first thing to do is to clone the repository:\n```bash\ngit clone https://github.com/MikhailGulkin/CleanGolangOrderApp\ncd CleanGolangOrderApp\n```\nAfter that create `.env` and `configs/app/prod.toml`. Examples for use lie next to these files.\nRun following command\n```bash\nmake up-prod\n```\n\n### TODO\n- [ ] Refactoring auto-tests\n- [ ] Configure CI\n- [ ] Create simple `CustomerService`","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikhailgulkin%2Fcleangolangorderapp","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikhailgulkin%2Fcleangolangorderapp","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikhailgulkin%2Fcleangolangorderapp/lists"}