Skip to content

rifqiyusrilmuslikhin/simple-go-grpc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

simple-go-grpc

A microservice project built with gRPC and Go, using Gin as the HTTP API Gateway.

Architecture

Client (REST/JSON)
        │
        ▼
   API Gateway (Gin) :8080
        │  gRPC (protobuf)
        ├──────────────────────┐
        ▼                      ▼
 user-service :50051   product-service :50052

Communication between services uses gRPC internally, while the API Gateway exposes a REST HTTP interface to the outside world.

Project Structure

simple-go-grpc/
│
├── pb/                           # Generated protobuf files
│
├── proto/                        # Protobuf definitions
│   ├── user.proto
│   └── product.proto
│
├── service/
│   ├── user/                     # User gRPC Service (port 50051)
│   │   ├── main.go
│   │   ├── server/
│   │   │   ├── user_server.go    # gRPC handler implementation
│   │   │   └── interceptors.go   # Logging & recovery interceptors
│   │   └── repository/
│   │       └── user_repo.go
│   │
│   └── product/                  # Product gRPC Service (port 50052)
│       ├── main.go
│       ├── server/
│       │   ├── product_server.go
│       │   └── interceptors.go
│       └── repository/
│           └── product_repo.go
│
├── api/                          # API Gateway (port 8080)
│   ├── main.go
│   ├── middleware/
│   │   ├── auth.go               # JWT validation middleware
│   │   └── rate_limiter.go       # Rate limiting per IP
│   ├── handler/
│   │   ├── auth_handler.go       # POST /auth/register, /auth/login
│   │   ├── user_handler.go       # GET /users/:id
│   │   └── product_handler.go    # CRUD /products
│   └── client/
│       ├── user_client.go        # gRPC client wrapper
│       └── product_client.go
│
├── Dockerfile                    # Single Dockerfile with ENTRY_PATH arg
├── docker-compose.yml
├── Makefile
└── go.mod

Tech Stack

  • Go 1.24
  • gRPC — internal service communication
  • Gin — HTTP API Gateway
  • Protobuf — service contracts & serialization
  • JWT — authentication
  • Docker — containerization

Getting Started

Prerequisites

# Install protoc
# macOS
brew install protobuf

# Ubuntu
apt-get install -y protobuf-compiler

# Windows
1. Download protoc from https://github.com/protocolbuffers/protobuf/releases
2. Extract and copy protoc.exe to a folder in your PATH
example: C:\Program Files\protoc\bin
3. Add the folder to System Environment Variables > PATH

# Install Go plugins
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

# Add to PATH
export PATH="$PATH:$(go env GOPATH)/bin"

Run with Docker

docker-compose up --build

Run Locally (3 terminals)

# Terminal 1 — user service
go run ./service/user/main.go

# Terminal 2 — product service
go run ./service/product/main.go

# Terminal 3 — api gateway
go run ./api/main.go

Generate Proto Files

# Use Makefile
make proto

# Or manual
protoc \
  --proto_path=proto \
  --go_out=pb --go_opt=paths=source_relative \
  --go-grpc_out=pb --go-grpc_opt=paths=source_relative \
  user.proto \
  product.proto

The generated results will go into the pb/ folder and produce:

  • *.pb.go — struct for every message
  • *_grpc.pb.go — interface server & client stub

API Endpoints

Auth (Public)

Method Endpoint Description
POST /api/v1/auth/register Register new user
POST /api/v1/auth/login Login & get JWT token

Users (Protected)

Method Endpoint Description
GET /api/v1/users/:id Get user by ID

Products (Protected)

Method Endpoint Description
POST /api/v1/products Create product
GET /api/v1/products List products (paginated)
GET /api/v1/products/:id Get product by ID

All protected routes require Authorization: Bearer <token> header.

Example Usage

# Register
curl -X POST http://localhost:8080/api/v1/auth/register \
  -H "Content-Type: application/json" \
  -d '{"name":"Budi","email":"budi@test.com","password":"password123"}'

# Login
curl -X POST http://localhost:8080/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"budi@test.com","password":"password123"}'

# Create product (use token from login response)
curl -X POST http://localhost:8080/api/v1/products \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Laptop","price":15000000,"stock":10}'

# List products
curl http://localhost:8080/api/v1/products?page=1&limit=10 \
  -H "Authorization: Bearer <token>"

Key Concepts

Why gRPC for internal services?

  • Faster than REST — uses binary protobuf instead of JSON
  • Strict contracts — proto files enforce API contracts at compile time
  • Not suitable for browser/frontend — use REST at the gateway layer instead

Proto as a contract .proto files define the message structures and service interfaces. After code generation, they produce Go structs, server interfaces, and client stubs — but database logic, error handling, and business logic are still written manually.

Single Dockerfile All services share one Dockerfile, differentiated by the ENTRY_PATH build argument:

args:
  ENTRY_PATH: service/user   # or service/product, api