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 products
  • GET /products/{id} - Get product
  • POST /products - Create product
  • PUT /products/{id} - Update product
  • DELETE /products/{id} - Delete product

🛒 Orders

  • GET /orders - List orders
  • GET /orders/{id} - Get order
  • POST /orders - Create order
  • PUT /orders/{id} - Update order
  • DELETE /orders/{id} - Cancel order

👥 Customers

  • GET /customers - List customers
  • GET /customers/{id} - Get customer
  • POST /customers - Create customer
  • PUT /customers/{id} - Update customer
  • DELETE /customers/{id} - Delete customer

📊 Inventory

  • GET /inventory - Inventory report
  • GET /inventory/{product_id} - Product inventory
  • POST /inventory/adjust - Adjust stock
  • GET /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