E-commerce API Example
Complete e-commerce backend with products, orders, and inventory management
SQL Schema
This example demonstrates a full e-commerce system with products, categories, orders, and inventory:
-- Categories for organizing products
CREATE TABLE categories (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(100) NOT NULL UNIQUE,
description TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Products catalog
CREATE TABLE products (
id BIGSERIAL PRIMARY KEY,
category_id BIGINT REFERENCES categories(id),
name VARCHAR(255) NOT NULL,
description TEXT,
price DECIMAL(10,2) NOT NULL,
sku VARCHAR(50) UNIQUE NOT NULL,
stock_quantity INTEGER DEFAULT 0,
is_active BOOLEAN DEFAULT TRUE,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Customer information
CREATE TABLE customers (
id BIGSERIAL PRIMARY KEY,
email VARCHAR(255) UNIQUE NOT NULL,
first_name VARCHAR(100) NOT NULL,
last_name VARCHAR(100) NOT NULL,
phone VARCHAR(20),
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Customer addresses
CREATE TABLE addresses (
id BIGSERIAL PRIMARY KEY,
customer_id BIGINT REFERENCES customers(id),
type VARCHAR(20) CHECK (type IN ('billing', 'shipping')),
street VARCHAR(255) NOT NULL,
city VARCHAR(100) NOT NULL,
state VARCHAR(100),
postal_code VARCHAR(20),
country VARCHAR(100) NOT NULL,
is_default BOOLEAN DEFAULT FALSE,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Orders
CREATE TABLE orders (
id BIGSERIAL PRIMARY KEY,
customer_id BIGINT REFERENCES customers(id),
status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'confirmed', 'shipped', 'delivered', 'cancelled')),
total_amount DECIMAL(10,2) NOT NULL,
shipping_address_id BIGINT REFERENCES addresses(id),
billing_address_id BIGINT REFERENCES addresses(id),
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW(),
updated_at TIMESTAMPTZ DEFAULT NOW()
);
-- Order items (products in each order)
CREATE TABLE order_items (
id BIGSERIAL PRIMARY KEY,
order_id BIGINT REFERENCES orders(id),
product_id BIGINT REFERENCES products(id),
quantity INTEGER NOT NULL,
unit_price DECIMAL(10,2) NOT NULL,
total_price DECIMAL(10,2) NOT NULL,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Inventory tracking
CREATE TABLE inventory_transactions (
id BIGSERIAL PRIMARY KEY,
product_id BIGINT REFERENCES products(id),
transaction_type VARCHAR(20) CHECK (transaction_type IN ('in', 'out', 'adjustment')),
quantity INTEGER NOT NULL,
reference_type VARCHAR(50), -- 'order', 'restock', 'adjustment'
reference_id BIGINT,
notes TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
Generate the Service
# Save the schema to ecommerce_schema.sql
go run . ecommerce-api ecommerce_schema.sql
Generated Project Structure
ecommerce-api/
├── domain/
│ ├── category.go
│ ├── product.go
│ ├── customer.go
│ ├── address.go
│ ├── order.go
│ ├── order_item.go
│ ├── inventory_transaction.go
│ └── interfaces.go
├── repository/
│ ├── category_repository.go
│ ├── product_repository.go
│ ├── customer_repository.go
│ ├── address_repository.go
│ ├── order_repository.go
│ ├── order_item_repository.go
│ └── inventory_transaction_repository.go
├── interactor/
│ ├── category_interactor.go
│ ├── product_interactor.go
│ ├── customer_interactor.go
│ ├── order_interactor.go
│ └── inventory_interactor.go
├── rest/
│ ├── category_handler.go
│ ├── product_handler.go
│ ├── customer_handler.go
│ ├── order_handler.go
│ ├── inventory_handler.go
│ └── middleware.go
└── application/
└── main.go
Generated API Endpoints
📦 Products
GET /products
- List productsGET /products/{id}
- Get productPOST /products
- Create productPUT /products/{id}
- Update productDELETE /products/{id}
- Delete product
🛒 Orders
GET /orders
- List ordersGET /orders/{id}
- Get orderPOST /orders
- Create orderPUT /orders/{id}
- Update orderDELETE /orders/{id}
- Cancel order
👥 Customers
GET /customers
- List customersGET /customers/{id}
- Get customerPOST /customers
- Create customerPUT /customers/{id}
- Update customerDELETE /customers/{id}
- Delete customer
📊 Inventory
GET /inventory
- Inventory reportGET /inventory/{product_id}
- Product inventoryPOST /inventory/adjust
- Adjust stockGET /inventory/transactions
- Transaction history
Sample Generated Code
Product Domain Entity
// domain/product.go
package domain
import (
"time"
"decimal"
)
type Product struct {
ID int64 `json:"id" db:"id"`
CategoryID *int64 `json:"category_id" db:"category_id"`
Name string `json:"name" db:"name"`
Description *string `json:"description" db:"description"`
Price decimal.Decimal `json:"price" db:"price"`
SKU string `json:"sku" db:"sku"`
StockQuantity int `json:"stock_quantity" db:"stock_quantity"`
IsActive bool `json:"is_active" db:"is_active"`
CreatedAt time.Time `json:"created_at" db:"created_at"`
UpdatedAt time.Time `json:"updated_at" db:"updated_at"`
}
type ProductRepository interface {
Create(product *Product) error
GetByID(id int64) (*Product, error)
GetBySKU(sku string) (*Product, error)
GetByCategory(categoryID int64) ([]*Product, error)
GetAll(offset, limit int) ([]*Product, error)
Update(product *Product) error
Delete(id int64) error
UpdateStock(id int64, quantity int) error
}
type ProductInteractor interface {
CreateProduct(product *Product) error
GetProduct(id int64) (*Product, error)
GetProductBySKU(sku string) (*Product, error)
GetProductsByCategory(categoryID int64) ([]*Product, error)
ListProducts(page, size int) ([]*Product, error)
UpdateProduct(product *Product) error
DeleteProduct(id int64) error
AdjustStock(id int64, quantity int) error
}
Order Handler Example
// rest/order_handler.go
func (h *OrderHandler) CreateOrder(w http.ResponseWriter, r *http.Request) {
var req CreateOrderRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, "Invalid JSON", http.StatusBadRequest)
return
}
// Validate request
if req.CustomerID == 0 {
http.Error(w, "customer_id is required", http.StatusBadRequest)
return
}
// Create order entity
order := &domain.Order{
CustomerID: req.CustomerID,
Status: "pending",
TotalAmount: req.TotalAmount,
ShippingAddressID: req.ShippingAddressID,
BillingAddressID: req.BillingAddressID,
Notes: req.Notes,
}
// Create order through interactor
if err := h.orderInteractor.CreateOrder(order); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// Return created order
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(order)
}
Usage Examples
Create a Product
curl -X POST http://localhost:8080/products \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token" \
-d '{
"category_id": 1,
"name": "Wireless Headphones",
"description": "High-quality wireless headphones with noise cancellation",
"price": "199.99",
"sku": "WH-001",
"stock_quantity": 50,
"is_active": true
}'
Create an Order
curl -X POST http://localhost:8080/orders \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-token" \
-d '{
"customer_id": 1,
"total_amount": "199.99",
"shipping_address_id": 1,
"billing_address_id": 1,
"items": [
{
"product_id": 1,
"quantity": 1,
"unit_price": "199.99"
}
]
}'
Get Inventory Report
curl http://localhost:8080/inventory \
-H "Authorization: Bearer your-token"
What's Included
🔐 Authentication
JWT-based authentication middleware protecting all endpoints
📊 Data Validation
Comprehensive request validation and error handling
🗄️ Database Layer
PostgreSQL integration with connection pooling
🐳 Docker Ready
Complete Docker setup with docker-compose