Home
Softono

Goshop

Open source MIT Go
380
Stars
87
Forks
0
Issues
3
Watchers
3 months
Last Commit

 About Goshop

E-Commerce system via Golang and ReactJS

Platforms

Web Self-hosted

Languages

Go

Links

Need Help Installing Goshop?

We provide expert installation service for this software. Our team will install, configure, and secure Goshop on your server. plans start at just $30.

GoShop

CI codecov Go Version License

A production-ready e-commerce application built with Go (REST + gRPC backend) and React (web frontend).

Architecture

The application runs two servers concurrently (backend) plus a React web frontend:

  • HTTP (REST) — Gin framework, port 8888
  • gRPC — port 8889, with JWT auth interceptor

Each domain (user, product, order, payment, notification) follows a ports-and-adapters layout:

internal/{domain}/
├── model/       # GORM models
├── dto/         # Request/response structs with validation tags
├── repository/  # Database access (depends on dbs.Database interface)
├── service/     # Business logic (depends on repository interfaces)
└── port/
    ├── http/    # Gin handlers and route registration
    └── grpc/    # gRPC handlers and server registration
Domain HTTP gRPC
user
product
order
payment
notification

Tech Stack

Backend

Concern Library
HTTP framework Gin v1.12
gRPC grpc-go v1.79
ORM GORM v1.31 + PostgreSQL
Cache go-redis v9
Auth JWT (golang-jwt v5)
Validation gocommon/validation
API Docs Swagger
Testing testify v1.11 + mockery
Proto codegen buf + protobuf v1.36

Frontend

Concern Library
Framework React 18 + TypeScript
Build tool Vite
Styling Tailwind CSS
Routing React Router v6
Data fetching TanStack Query
Forms React Hook Form + Zod
HTTP client Axios

Prerequisites

  • Go 1.26+
  • Node.js 18+
  • PostgreSQL
  • Redis

Docker Compose for local dependencies: docker-compose-template

Getting Started

1. Clone and configure

git clone https://github.com/quangdangfit/goshop.git
cd goshop
cp config.sample.yaml config.yaml

Edit config.yaml (lives at the repo root and is loaded from the working directory; override with CONFIG_FILE=/path/to/config.yaml):

environment: production
http_port: 8888
grpc_port: 8889
auth_secret: your-secret-key
database_uri: postgres://username:password@localhost:5432/goshop
redis_uri: localhost:6379
redis_password:
redis_db: 0

# Stripe (payments)
stripe_secret_key: sk_test_xxx
stripe_webhook_secret: whsec_xxx
stripe_publishable_key: pk_test_xxx

# SMTP (notifications — point at MailHog locally: host=localhost, port=1025)
smtp_host:
smtp_port: 25
email_from: [email protected]

2. Apply database migrations

The app no longer runs AutoMigrate — schema lives in versioned SQL files under migrations/ and is applied with golang-migrate.

brew install golang-migrate   # or: go install -tags 'postgres' github.com/golang-migrate/migrate/v4/cmd/migrate@latest
DATABASE_URI="postgres://username:password@localhost:5432/goshop?sslmode=disable" make migrate-up

See migrations/README.md for conventions and the production / Kubernetes init-container pattern.

3. Run the backend

go run cmd/api/main.go
INFO    HTTP server is listening on PORT: 8888
INFO    GRPC server is listening on PORT: 8889

4. Run the web frontend

cd web
npm install
npm run dev

Web UI: http://localhost:3000

The frontend proxies all /api requests to the backend at http://localhost:8888, so both servers must be running.

5. Browse the API

Swagger UI: http://localhost:8888/swagger/index.html

API Reference

Auth

Method Endpoint Description
POST /api/v1/auth/register Register
POST /api/v1/auth/login Login
POST /api/v1/auth/refresh Refresh access token
GET /api/v1/auth/me Get current user
PUT /api/v1/auth/change-password Change password

Addresses

Method Endpoint Description
GET /api/v1/addresses List my addresses
POST /api/v1/addresses Create address
GET /api/v1/addresses/:id Get address
PUT /api/v1/addresses/:id Update address
DELETE /api/v1/addresses/:id Delete address
PUT /api/v1/addresses/:id/default Set default address

Wishlist

Method Endpoint Description
GET /api/v1/wishlist Get my wishlist
POST /api/v1/wishlist Add product to wishlist
DELETE /api/v1/wishlist/:productId Remove from wishlist

Categories

Method Endpoint Description
GET /api/v1/categories List categories
GET /api/v1/categories/:id Get category
POST /api/v1/categories Create category (auth)
PUT /api/v1/categories/:id Update category (auth)
DELETE /api/v1/categories/:id Delete category (auth)

Products

Method Endpoint Description
GET /api/v1/products List products (cached)
GET /api/v1/products/:id Get product (cached)
POST /api/v1/products Create product (auth)
PUT /api/v1/products/:id Update product (auth)
GET /api/v1/products/:id/reviews List product reviews
POST /api/v1/products/:id/reviews Create review (auth)
PUT /api/v1/products/:id/reviews/:reviewId Update review (auth)
DELETE /api/v1/products/:id/reviews/:reviewId Delete review (auth)

Orders

Method Endpoint Description
POST /api/v1/orders Place order
GET /api/v1/orders List my orders
GET /api/v1/orders/:id Get order details
PUT /api/v1/orders/:id/cancel Cancel order
PUT /api/v1/orders/:id/status Update order status (admin)

Coupons

Method Endpoint Description
POST /api/v1/coupons Create coupon (auth)
GET /api/v1/coupons/:code Get coupon by code

Payments

Method Endpoint Description
POST /api/v1/orders/:id/payment-intent Create Stripe PaymentIntent for order
POST /api/v1/webhooks/stripe Stripe webhook (signature-verified, no JWT)
GET /api/v1/config/public Public client config (Stripe publishable key)

Notifications

Method Endpoint Description
GET /api/v1/me/notification-preferences Get my notification preferences
PUT /api/v1/me/notification-preferences Update notification preferences

Cart is client-side only (persisted in the browser). Order creation accepts the full line items and the server re-validates products, prices, and stock.

Development

Run all unit tests with coverage

make unittest

Run a single test suite

go test ./internal/product/service/... -v -run TestProductServiceTestSuite

Run a single test case

go test ./internal/product/service/... -v -run TestProductServiceTestSuite/TestCreateSuccess

Run integration tests

Integration suites live under tests/integration/ (per-domain: order, payment, user, product, notification), are gated by the //go:build integration tag, and use testcontainers to spin up real Postgres / Redis / MailHog. They are invisible to make unittest / go test ./....

make integration
# = go test -tags=integration -timeout 9000s -v -coverprofile=coverage.integration.out ./tests/integration/...

Requirements: a running Docker daemon. The shared helpers (StartPostgres, StartRedis, NewHTTPEnv) live in tests/testutil/. CI runs the integration job in parallel with the unit job; both upload coverage to Codecov under the unittest / integration flags.

Database migrations

make migrate-up                  # apply all pending migrations
make migrate-down                # roll back the latest migration
make migrate-status              # print current schema version
make migrate-new name=add_index  # scaffold the next NNNN_*.{up,down}.sql pair

Set DATABASE_URI in your shell to override the default (postgres://postgres:test@localhost:5432/goshop?sslmode=disable).

Regenerate mocks

make mock

Regenerate Swagger docs

make doc

Regenerate proto (Uses https://buf.build)

cd proto && make build