How tdenkov123/garchive works
Purpose and Entry Point
GArchive is a Go gRPC service for file metadata and upload lifecycle management. File bytes are stored in S3-compatible MinIO; PostgreSQL holds metadata and multipart state; Redis accelerates reads; Kafka receives domain events. The process starts at cmd/server/main.go, which composes dependencies through internal/app/app.go.
Public API Contract
The gRPC contract defines single-upload, multipart-upload, read/list, download URL, and delete operations. Generated server/client bindings are under api/gen/file/v1/file_grpc.pb.go; the source-of-truth schema is api/proto/file/v1/file.proto. Request handling enters through internal/grpc/handler.go.
Application and Service Layer
internal/service/file_service.go implements file lifecycle operations: create metadata, issue presigned upload/download URLs, confirm checksums, read/list records, and soft-delete files. internal/service/multipart_service.go owns multipart state transitions, part URL issuance/reporting, completion, and abort. internal/service/adapters.go defines the boundary-facing dependencies consumed by services, keeping business workflows independent of concrete infrastructure.
Request Control Plane
gRPC middleware applies cross-cutting controls before handlers: JWT identity extraction/authentication, rate limiting, validation, logging/metrics/error handling. Relevant paths are internal/grpc/middleware/interceptors.go, internal/grpc/middleware/ratelimit.go, and internal/auth/jwt.go. Authenticated ownership and request context are propagated through internal/auth/context.go; audit records are emitted via internal/audit/audit.go.
Persistence, Cache, and Object Storage
PostgreSQL is the authoritative metadata store, with schema migrations for files and multipart uploads in internal/repository/postgres/migrations/001_init.sql and internal/repository/postgres/migrations/002_multipart.sql. Repository implementations live in internal/repository/postgres/file.go. Redis caching is isolated behind internal/cache/redis/cache.go. MinIO access, including presigned URL and object lifecycle operations, is encapsulated in internal/storage/minio/client.go.
Events and Lifecycle Flow
For a single upload, the service persists a pending file record, returns a presigned PUT URL, then validates a supplied SHA-256 checksum during confirmation before marking the record ready. Multipart uploads persist upload/part progress until completion or abort. Ready and deletion lifecycle changes publish Kafka domain events through internal/service/events.go and internal/events/kafka/publisher.go. Object operations cross the MinIO boundary; metadata transitions cross PostgreSQL; cache invalidation/population accompanies read/write paths.
Runtime and Deployment Boundaries
The service runs as a containerized Go process (Dockerfile) and exposes gRPC on port 50051, Prometheus metrics on 9090, and gRPC health. Local orchestration is defined in docker-compose.yml; production composition is in docker-compose.prod.yml. Core external runtime services are PostgreSQL, Redis, MinIO, and Kafka; optional profiles add Keycloak for OIDC demonstration and Jaeger observability. TLS server credentials are handled by internal/tlsutil/credentials.go, while configuration is centralized in internal/config/config.go.
Main entry points: adapters.go Service dependency ports · interceptors.go Request interceptors · handler.go File RPC handler · file_service.go File lifecycle service
Components 20
Runtime
- Go service container · Exposes gRPC, health, and Prometheus endpoints.
Dockerfile - Dependency composition
internal/app/app.go
gRPC edge
- File gRPC contract · Defines upload, multipart, read, URL, and delete RPCs.
api/proto/file/v1/file.proto - Generated gRPC bindings
api/gen/file/v1/file_grpc.pb.go - Request interceptors · Applies auth, validation, rate limits, logging, metrics, and errors.
internal/grpc/middleware/interceptors.go - Rate limiting
internal/grpc/middleware/ratelimit.go - File RPC handler
internal/grpc/handler.go - JWT identity · Propagates authenticated ownership through request context.
internal/auth/jwt.go
Application
- File lifecycle service · Manages single-upload metadata, URLs, checksums, reads, and deletion.
internal/service/file_service.go - Multipart lifecycle service · Manages upload state, parts, completion, and abort.
internal/service/multipart_service.go - Service dependency ports · Keeps lifecycle workflows independent of infrastructure.
internal/service/adapters.go - Lifecycle event publisher · Publishes ready and deletion changes.
internal/service/events.go
Infrastructure
- PostgreSQL repository · Authoritative files and multipart state.
internal/repository/postgres/file.go - Redis cache · Caches read paths and supports invalidation.
internal/cache/redis/cache.go - MinIO storage client · Issues presigned URLs and performs object lifecycle operations.
internal/storage/minio/client.go - Kafka publisher
internal/events/kafka/publisher.go
External services
- PostgreSQL · Schema includes file and multipart records.
internal/repository/postgres/migrations/001_init.sql - Redis
- MinIO · Stores file bytes.
- Kafka
Connections 21
- Go service container → Dependency composition: starts
- Dependency composition → Request interceptors: configures
- File gRPC contract → Generated gRPC bindings: generates
- Generated gRPC bindings → File RPC handler: server interface
- Request interceptors → Rate limiting: enforces
- Request interceptors → JWT identity: authenticates
- Request interceptors → File RPC handler: wraps
- File RPC handler → File lifecycle service: single-file RPCs
- File RPC handler → Multipart lifecycle service: multipart RPCs
- File lifecycle service → Service dependency ports: uses ports
- Multipart lifecycle service → Service dependency ports: uses ports
- File lifecycle service → Lifecycle event publisher: ready/delete
- Multipart lifecycle service → Lifecycle event publisher: completion
- Service dependency ports → PostgreSQL repository: metadata state
- Service dependency ports → Redis cache: cache reads/writes
- Service dependency ports → MinIO storage client: presigned/object operations
- Lifecycle event publisher → Kafka publisher: publishes
- PostgreSQL repository → PostgreSQL: persists
- Redis cache → Redis: caches
- MinIO storage client → MinIO: stores objects
- Kafka publisher → Kafka: emits events