{"id":22591708,"url":"https://github.com/subliker/track-parcel-service","last_synced_at":"2026-05-07T18:31:48.064Z","repository":{"id":256755311,"uuid":"856322869","full_name":"subliker/track-parcel-service","owner":"subliker","description":"Microservices-based parcel tracking system with Telegram bot integration, message broker, and gRPC communication, designed for seamless parcel management and notifications.","archived":false,"fork":false,"pushed_at":"2025-01-08T20:55:22.000Z","size":2078,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-11T17:52:44.682Z","etag":null,"topics":["elk","golang","goose","grpc","kubernetes","microservice","rabbitmq"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/subliker.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":"2024-09-12T11:40:37.000Z","updated_at":"2025-01-05T19:28:24.000Z","dependencies_parsed_at":null,"dependency_job_id":"b81b3745-f48a-426a-ba3c-da1256d91e4e","html_url":"https://github.com/subliker/track-parcel-service","commit_stats":null,"previous_names":["subliker/track-parcel-service"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subliker%2Ftrack-parcel-service","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subliker%2Ftrack-parcel-service/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subliker%2Ftrack-parcel-service/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/subliker%2Ftrack-parcel-service/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/subliker","download_url":"https://codeload.github.com/subliker/track-parcel-service/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246078713,"owners_count":20720193,"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":["elk","golang","goose","grpc","kubernetes","microservice","rabbitmq"],"created_at":"2024-12-08T09:13:42.317Z","updated_at":"2026-05-07T18:31:43.041Z","avatar_url":"https://github.com/subliker.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Track parcel service\n\nThis documentation is also available in Russian [there](./README_RU.md).\n\n# Table of Contents\n\n1. [Project Idea](#project-idea)\n2. [Project Setup](#project-setup)\n3. [Selected Tools](#selected-tools)\n\n\u003cimg src=\"./assets/track-parcel-service.svg\"\u003e\n\n## Project Idea\nThis service was implemented to gain experience working with a project structure based on microservice architecture, describing gRPC interaction between services, using a message broker, and deploying the project in a clustered environment.\n\nThe **Parcel Tracking Service** was a perfect fit for these requirements. The service was initially split into 6 independent microservices with their own areas of responsibility:\n\n- **Account Service**: Works with user data in the system for display, authentication, and authorization.\n- **User Client Service**: Works with the Telegram API, allows users to receive information about parcels, subscribe to updates via the Telegram bot interface. It is used for registering users in the system by their *Telegram user id*.\n- **Parcel Service for Users**: Used for retrieving parcel data and managing user subscriptions.\n- **Manager Client Service**: Works with the Telegram API, allows managers to create, modify, and update parcels in the system. It is used for registering managers in the system by their *Telegram user id*.\n- **Parcel Service for Managers**: Used for managing parcel data by managers. When parcel data is updated, an event is sent to the notification service.\n- **Notification Service**: Works with other services via a message broker. It receives events from the queue for notifications and then sends the collected notifications to services responsible for sending them.\n\n## Project Setup\nThe setup instructions use task commands. You need to install [Taskfile](https://taskfile.dev/) or refer to the commands in the `Taskfile.yml` and manually enter them 😈.\n\n### Test Environment\n#### Service Configuration\nIf you don't want to dig into the configuration of each microservice, you can run the project using the **default** configuration. To do this, use the `task set-example` command. The environment variable and configuration files will be copied to the actual configs.\n\nFor **manual** configuration, you can also use the default configurations (which describe all the fields) and modify them according to your needs, or, by reviewing the config structure or documentation, create your own.\n\nService configs are located in `configs/config.toml`. Configuration of databases, brokers, and other non-Golang services happens using environment variables in `docker-compose`.\n\nTo make the client-bots work, it is **important** to specify tokens in the configuration of the `internal/services/manager_bot_service` and `internal/services/user_bot_service` services.\n\nFor the initial setup, run the migrations using: `task migrate-all-up`. For testing purposes, you can migrate test data using: `task migrate-test-all-up`.\n\nNow, you can start all services with `docker compose up -d` in the project root directory and `task run` in each service directory.\n\n### Cluster Environment\nYou should already have `kubectl` configured for this project.\n\nIn the `k8s_example` directory, there are example service configurations. To make the service work, you only need to add base64-encoded bot tokens to `k8s_example/services/user_bot_service.yml` and `k8s_example/services/manager_bot_service.yml`.\n\nTo encrypt the token, run the command `echo -n \"\u003cyour-token\u003e\" | base64` and copy the resulting string into the Secret in the above-mentioned configs.\n\nEnsure that all services are configured properly. Now you can apply the configurations:\n```sh\n// start broker\nkubectl apply -f k8s_example/broker\n\n// start databases, migrations and admin panel\nkubectl apply -f k8s_example/database\nkubectl apply -f k8s_example/database/migration\nkubectl apply -f k8s_example/database/admin\n\n// Start services\nkubectl apply -f k8s_example/services\n```\n\n## Selected Tools\n### Service Development\n#### Programming Language\nGo (Golang) was chosen for service development, which is my main programming language. There are several reasons why I prefer this language for this type of service:\n\n- Go allows writing code in a consistent style, focusing more on the logic of the code than on its implementation, which is important.\n- The language's rich toolset and the large community with libraries provide many ready-made solutions.\n- Built-in code generation support makes it easy to work with gRPC, localizations, documentation, and other tools.\n- The module and package hierarchy allows for flexible code reuse and abstraction of service functions from one another.\n- The final image of the containerized application is only a few dozen megabytes when properly containerized.\n- Built-in tools for context handling allow easy integration of graceful shutdowns, request rollbacks, etc.\n\n#### Interface-Based Approach\nInterfaces are used for the tools and components of the services. These interfaces interact with the application layers. This approach was chosen to simplify testing (mocking) and to allow using multiple implementations of tools and components.\n\nFor example, integrating a different logger into a microservice is as simple as defining and importing a new implementation. The interface implementations return a ready-to-use interface after calling the `New` function.\n\nIn the `main` package, the choice of implementations is made (via flags or configuration), which are then passed to the application layers as interfaces.\n\n#### Logging\nThe logging tool in all services is [uber-go/zap](https://github.com/uber-go/zap).\n\nZap was chosen for its rich set of logging tools, flexible log formatting, speed, and the ability to use remote log aggregators (for ELK and similar systems).\n\nThe interface and implementation are described in `pkg/logger` and `pkg/logger/zap`, respectively. In `main.go`, the `New` function from the `zap` package is called to create the logger, which is then passed to the application layers.\n\nThe logger has methods for formatted (Infof, Warnf, etc.) and unformatted (Info, Warn, etc.) logging, as well as the ability to create a logger with a field that can store important data (e.g., the current layer or handler).\n\nFor ELK system integration, the zap implementation supports a remote source for log forwarding. The target address is provided as an argument when creating the logger.\n\n#### Configuration\nThe tool used for reading service configurations is [spf13/viper](https://github.com/spf13/viper), with the configuration files written in TOML format.\n\nViper was chosen for its ability to read configurations from both environment variables and files, support for default values, and automatic configuration structure assembly.\n\nThe configuration initializer is located in the `pkg/config` module, which should be imported to configure Viper by default. The configuration structure, reading, default value setting, and validation are provided in each service's package in `internal/config`.\n\nConfiguration validation is performed using a global validator.\n\n#### Containerization\nThe microservices containerization happens in two stages. In the first stage, the project is built into a Go-based image. In the second stage, a minimal Alpine image is used, with the built application copied from the first stage. Thus, the final image contains only the application build and an empty Alpine Linux system.\n\nAlpine was chosen for its small size and the availability of standard utilities for command-line access.\n\n#### REST API Server\nThe **Parcel Service for Managers** uses a REST API server to provide access to parcel management via external automated systems.\n\nThe router from [gorilla/mux](https://github.com/gorilla/mux) is used for routing. It was chosen for its simplicity, speed, and interaction with standard (from the internal package) HTTP structures and interfaces.\n\nFor automatic documentation generation from annotations, [swaggo/swag](https://github.com/swaggo/swag) is used.\n\n#### Stores and Repositories\nFor working with data storage, we use stores and repositories. This approach also uses interfaces and implementations, so services are not dependent on the choice of database or storage.\n\nSQL queries are generated using [Masterminds/squirrel](https://github.com/Masterminds/squirrel), which simplifies and types query creation.\n\n#### Instruction Overview\nFor quick and easy interaction with services, we use the [Taskfile](https://taskfile.dev/) (an alternative to Makefile). It is used in the project to define build commands, apply standard configurations, run services, generate code, and more.\n\n### Test Environment\nTo set up a test or development environment, we use `docker-compose` and the standard microservice configuration, which allows you to run services locally without conflicts.\n\nIn `docker-compose`, databases, the message broker, and ELK services are started. The remaining services can be started via `go run`.\n\n### Cluster Environment\nThe orchestration tool used in this project is Kubernetes. In the `k8s_example` directory, microservice configurations, migration jobs, database configurations, and message broker settings are provided.\n\nMicroservices were successfully tested in the cluster environment.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsubliker%2Ftrack-parcel-service","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsubliker%2Ftrack-parcel-service","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsubliker%2Ftrack-parcel-service/lists"}