{"id":22399799,"url":"https://github.com/mrkazzila/shortener_url_api","last_synced_at":"2026-04-10T17:05:40.457Z","repository":{"id":188730243,"uuid":"674622560","full_name":"mrKazzila/shortener_url_api","owner":"mrKazzila","description":"!!!ON HOLD!!!   Tiny url api using FastApi.","archived":false,"fork":false,"pushed_at":"2025-01-03T08:33:07.000Z","size":722,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-01T05:41:33.106Z","etag":null,"topics":["alembic","docker","docker-compose","fastapi","poetry","postgres","pytest","sqlachemy"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":false,"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/mrKazzila.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-08-04T11:48:22.000Z","updated_at":"2025-01-03T08:33:14.000Z","dependencies_parsed_at":"2024-03-12T18:52:17.655Z","dependency_job_id":"873ccfe8-c7c2-462d-b825-c4cec38af016","html_url":"https://github.com/mrKazzila/shortener_url_api","commit_stats":null,"previous_names":["mrkazzila/shortener","mrkazzila/shortener_url_api"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrKazzila%2Fshortener_url_api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrKazzila%2Fshortener_url_api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrKazzila%2Fshortener_url_api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrKazzila%2Fshortener_url_api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrKazzila","download_url":"https://codeload.github.com/mrKazzila/shortener_url_api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245755679,"owners_count":20667027,"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":["alembic","docker","docker-compose","fastapi","poetry","postgres","pytest","sqlachemy"],"created_at":"2024-12-05T08:10:03.502Z","updated_at":"2026-04-10T17:05:40.440Z","avatar_url":"https://github.com/mrKazzila.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# URL Shortener gRPC API\n\n---\n\n## Features\n\n- High-performance async **gRPC API**\n- URL shortening with PostgreSQL + Redis caching\n- Event-driven via Kafka (FastStream)\n- Full DDD / Clean Architecture setup\n- Async ORM with SQLAlchemy \u0026 Alembic migrations\n- Unit of Work \u0026 transaction management\n- DI with Dishka, testing with pytest\n- Observability stack: Prometheus, Grafana, Loki, Promtail\n\n---\n\n## Tech Stack\n| Layer               | Tools \u0026 Tech                            |\n|---------------------|-----------------------------------------|\n| API                 | gRPC (protobuf)                         |\n| DB \u0026 ORM            | PostgreSQL, SQLAlchemy (async), Alembic |\n| Caching             | Redis                                   |\n| Messaging           | Kafka (FastStream)                      |\n| DI \u0026 Architecture   | Dishka, DDD, Clean Architecture         |\n| Testing \u0026 QA        | pytest, Ruff, Pyright                   |\n| Observability       | Prometheus, Grafana, Loki, Promtail     |\n| DevOps \u0026 Containers | Docker, Docker Compose, Justfile        |\n\n---\n\n## Documentation\n\n### gRPC UI (grpcui)\n\n```bash\ngrpcui -plaintext localhost:50051\n````\n\n### Additional docs\n\n* [gRPC docs](docs/grpc/grpc.md)\n\n---\n\n## Architecture Diagrams\n\n\u003cdetails\u003e\n\u003csummary\u003eDB Schema\u003c/summary\u003e\n\u003cimg src=\"docs/images/schemas/db.png\" alt=\"DB Schema\"/\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eClasses Diagram\u003c/summary\u003e\n\u003cimg src=\"docs/images/schemas/classes_shortener.png\" alt=\"Classes Diagram\"/\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003ePackages Diagram\u003c/summary\u003e\n\u003cimg src=\"docs/images/schemas/packages_shortener.png\" alt=\"Packages Diagram\"/\u003e\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eSystem Diagram\u003c/summary\u003e\n\u003cp\u003eTODO: Add Excalidraw system diagram\u003c/p\u003e\n\u003c/details\u003e\n\n---\n\n## Quick Start (Docker \u0026 Just)\n1. Clone repo\n```bash\n  git clone git@github.com:mrKazzila/shortener_url_api.git\n  cd shortener_url_api/backend\n```\n\n2. Configure env \u0026 pgbouncer (edit `env.env` and `backend/docker/compose/infra/pgbouncer/userlist.txt`)\n\n\n3. Start infrastructure\n```bash\n  just infra-up\n```\n\n4. Run app (1 1 = partitions \u0026 replicas)\n```bash\n  just app-bootstrap 1 1\n```\n\n5. Optional monitoring stack\n```bash\n  just mon-up\n```\n\n6.  See all available commands\n```bash\n  just\n````\n\n---\n\n## Local Load Testing (gRPC)\n\nFor local load testing, I use **ghz**.\n\n### Example: CreateShortUrl\n\n```bash\nghz --insecure \\\n  --proto ./proto/shortener_app/v1/shortener_app.proto \\\n  --call shortener_app.v1.ShortenerService.CreateShortUrl \\\n  -d '{\"target_url\":\"https://example.com\"}' \\\n  -c 50 \\\n  --duration 10m \\\n  --import-paths ./proto \\\n  localhost:50051\n```\n\nExample results:\n\n* ~800k requests in 10 minutes\n* ~1330 RPS\n* Avg latency ~37ms\n* P99 ~91ms\n* Occasional `Unavailable` errors on the local network during aggressive competition\n\n---\n\n## ⚠️ Over-engineering Note\n\n\u003cdetails\u003e\n\u003csummary\u003eWhy so many technologies?\u003c/summary\u003e\nThis project intentionally uses advanced technologies (Kafka, Redis, DI, DDD, async ORM) for a simple URL shortener to showcase scalable, maintainable microservice design.\n\u003c/details\u003e\n\n---\n\n[![GitHub](https://img.shields.io/badge/github-mrKazzila-blue?logo=github)](https://github.com/mrKazzila)\n[![Portfolio](https://img.shields.io/badge/portfolio-mrkazzila.com-orange)](https://mrkazzila.com)\n[![LinkedIn](https://img.shields.io/badge/linkedin-i--kazakov-blue?logo=linkedin)](https://www.linkedin.com/in/i-kazakov/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrkazzila%2Fshortener_url_api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrkazzila%2Fshortener_url_api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrkazzila%2Fshortener_url_api/lists"}