go-m2rest
August 10, 2026 · View on GitHub
A Modern and Robust Golang Library for Magento 2 REST API
This Golang library provides a comprehensive interface for interacting with the Magento 2 REST API. Built with modern Go practices (1.25+), it features a context-aware read/sync API, structured logging, hardened retries, and an offline (httptest-based) unit test suite.
Features
- Context support: All new read/sync functions are
context.Context-first (GetProductsPage,IterateProducts, ...); genericGetRouteAndDecodeCtx/PostRouteAndDecodeCtxhelpers are available on the client, and the legacy non-ctx API keeps working - Catalog sync API: Paginated product/attribute listing with iteration helpers, attribute sets, category tree, store views and websites
- Comprehensive Logging: Structured logging with zerolog; silent (no-op) by default, opt-in via
SetZeroLogger/EnableDebugLogging - Robust Error Handling: Typed
APIError(status code, endpoint, truncated body) that still matches theErrNotFound/ErrBadRequestsentinels viaerrors.Is - Authentication Support: Multiple authentication methods including Integration tokens, Customer tokens, and Admin credentials
- Extensive API Coverage:
- Products: Simple, configurable, bundle, grouped, and virtual products
- Categories: Full hierarchy management and product assignments
- Attributes: Create and manage product attributes with options
- Carts: Guest and customer cart management with full checkout flow
- Orders: Order retrieval, updates, and comments
- Stock Management: Inventory updates and stock status
- Performance & Reliability:
- 30s per-attempt timeout by default (
SetTimeoutto override) - Automatic retries on 429/500/502/503/504 honoring the
Retry-Afterheader (SetRetryPolicyto override) - Connection pooling via resty v2
- 30s per-attempt timeout by default (
Getting Started
Prerequisites
- Go 1.25+ - Required for modern Go features and latest security patches
- Magento 2 Instance - With REST API enabled
- API Credentials - Integration token or admin/customer credentials
Installation
go get github.com/florinel-chis/go-m2rest
Quick Start
package main
import (
"log"
"github.com/florinel-chis/go-m2rest"
)
func main() {
// Configure store connection
storeConfig := &magento2.StoreConfig{
Scheme: "https",
HostName: "your-store.com",
StoreCode: "default",
}
// Create API client with integration token
client, err := magento2.NewAPIClientFromIntegration(
storeConfig,
"your_integration_token",
)
if err != nil {
log.Fatal(err)
}
// Create a simple product
product := magento2.Product{
Sku: "test-product-001",
Name: "Test Product",
Price: 29.99,
TypeID: "simple",
AttributeSetID: 4,
Status: 1,
Visibility: 4,
Weight: 1.0,
}
mProduct, err := magento2.CreateOrReplaceProduct(&product, true, client)
if err != nil {
log.Fatal(err)
}
log.Printf("Created product: %s (ID: %d)",
mProduct.Product.Sku,
mProduct.Product.ID)
}
Catalog sync
The library ships a context-aware read API designed for synchronizing a catalog into another system: paginated listing with automatic iteration, attribute metadata, attribute sets, the category tree, and store scopes.
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Minute)
defer cancel()
// Iterate all products updated since the last sync run. Pagination is
// handled internally (stops on total_count or an empty page).
opts := magento2.ListOptions{
PageSize: 200,
SortField: "updated_at",
SortDir: "ASC",
Criteria: []magento2.SearchQueryCriteria{{
Fields: []magento2.FilterFields{{
Field: magento2.Filter{FilterGroups: 0, Filters: 0, FilterFor: "updated_at"},
Value: magento2.Filter{FilterGroups: 0, Filters: 0, FilterFor: "2026-01-01 00:00:00"},
ConditionType: magento2.Filter{FilterGroups: 0, Filters: 0, FilterFor: "gt"},
}},
}},
}
err := magento2.IterateProducts(ctx, client, opts, func(p magento2.Product) error {
fmt.Println(p.Sku, p.Name, p.UpdatedAt)
return nil // return an error to abort the iteration
})
// Fetch a single page of attribute metadata.
attrPage, err := magento2.GetAttributesPage(ctx, client, magento2.ListOptions{PageSize: 100, CurrentPage: 1})
for _, a := range attrPage.Items {
fmt.Println(a.AttributeCode, bool(a.IsFilterable))
}
// Related helpers:
// magento2.GetProductsPage(ctx, client, opts) // single page of products
// magento2.IterateAttributes(ctx, client, opts, fn)
// magento2.GetAttributeSetsList(ctx, client) // all attribute sets
// magento2.GetAttributeSetAttributes(ctx, client, setID)
// magento2.GetCategoryTree(ctx, client) // nested CategoryTreeNode
// magento2.GetStoreViews(ctx, client)
// magento2.GetWebsites(ctx, client)
Notes:
ListOptions.Encode()produces the MagentosearchCriteriaquery parameters (filter groups,pageSize,currentPage,sortOrders). APageSize <= 0encodes as 100.Attribute.IsFilterableandAttribute.IsFilterableInSearchare of typeFlexBool, which tolerates the mixed encodings Magento emits (true/false,0/1/2,"0"/"1"/"2","true"/"false") and always marshals as a plain JSON bool.
Testing
The library includes an offline unit test suite (httptest-based, no live Magento needed) plus optional live functional tests.
Running Tests
# Run all tests; the live functional tests under ./tests are skipped
# automatically when MAGENTO_HOST is not set
go test ./...
# Run the live tests against a real Magento instance
MAGENTO_HOST=http://magento.local MAGENTO_BEARER_TOKEN=token go test ./tests -v
# Run specific test
go test ./tests -run TestAdvancedProducts_VirtualProduct -v
Test Configuration
Create a .env file in the project root:
MAGENTO_HOST=http://your-magento-site.com
MAGENTO_BEARER_TOKEN=your_integration_token
MAGENTO_STORE_CODE=default
TEST_DEBUG=true
Docker Support
The library includes Docker support for easy testing and development without installing Go locally.
Quick Start with Docker
# One-line command to run all tests
docker run --rm -e MAGENTO_BEARER_TOKEN=your_token_here -e MAGENTO_HOST=http://magento.local ghcr.io/florinel-chis/go-m2rest:latest
# Or build and run locally
docker build -t go-m2rest . && docker run --rm -e MAGENTO_BEARER_TOKEN=your_token go-m2rest
Using Docker Compose
# Run all tests
MAGENTO_BEARER_TOKEN=your_token docker-compose run --rm test
# Run specific test
MAGENTO_BEARER_TOKEN=your_token TEST_NAME=TestAdvancedProducts_VirtualProduct docker-compose run --rm test-specific
# Development mode with live code reload
docker-compose run --rm dev
Using the Docker Helper Script
For even easier usage, use the included docker-run.sh script:
# Run all tests
MAGENTO_BEARER_TOKEN=your_token ./docker-run.sh test
# Run specific test
MAGENTO_BEARER_TOKEN=your_token TEST_NAME=TestAdvancedProducts_VirtualProduct ./docker-run.sh test-specific
# Quick connectivity test
MAGENTO_BEARER_TOKEN=your_token ./docker-run.sh test-quick
# Create 50 products
MAGENTO_BEARER_TOKEN=your_token ./docker-run.sh bulk-create 50
# Update stock from CSV
MAGENTO_BEARER_TOKEN=your_token ./docker-run.sh bulk-update stock_updates.csv
# Open shell in container
./docker-run.sh shell
# Build Docker images
./docker-run.sh build
Docker Environment Variables
The Docker setup supports all the same environment variables as the native setup:
MAGENTO_HOST- Magento URL (default:http://magento.local)MAGENTO_BEARER_TOKEN- Integration token (required)MAGENTO_STORE_CODE- Store code (default:all)TEST_DEBUG- Enable debug logging (default:true)TEST_NAME- Specific test to run (for test-specific command)
Building Custom Docker Image
You can customize the Dockerfile to include your own environment variables:
# In Dockerfile, update the ENV section
ENV MAGENTO_HOST=http://your-magento.com \
MAGENTO_BEARER_TOKEN=your_permanent_token \
MAGENTO_STORE_CODE=your_store
Then build and run:
docker build -t my-m2rest .
docker run --rm my-m2rest
Bulk Operations
The library includes utilities for bulk operations. See the scripts/ directory for examples.
Bulk Product Creation and Stock Update
cd scripts
./run_bulk_update.sh stock_updates.csv 100 10 both
This will:
- Create 100 simple products
- Update their stock from the CSV file
- Use 10 concurrent operations
Advanced Usage
Working with Different Product Types
// Virtual Product (no shipping)
virtualProduct := magento2.Product{
Sku: "virtual-service-001",
Name: "Virtual Service",
TypeID: "virtual",
Price: 99.99,
// No weight needed for virtual products
}
// Grouped Product
groupedProduct := magento2.Product{
Sku: "grouped-product-001",
Name: "Product Bundle",
TypeID: "grouped",
// Price comes from associated products
}
// Configurable Product
configurableProduct := magento2.Product{
Sku: "configurable-001",
Name: "T-Shirt",
TypeID: "configurable",
// Requires attribute configuration
}
Cart Operations
// Create guest cart
guestCart, err := magento2.NewGuestCartFromAPIClient(client)
// Add items
item := magento2.CartItem{
Sku: "test-product-001",
Qty: 2,
QuoteID: guestCart.QuoteID,
}
err = guestCart.AddItems([]magento2.CartItem{item})
// Estimate shipping
shippingAddr := &magento2.ShippingAddress{
Address: magento2.Address{
CountryID: "US",
Postcode: "10001",
City: "New York",
Street: []string{"123 Main St"},
Firstname: "John",
Lastname: "Doe",
Telephone: "555-1234",
Email: "john@example.com",
},
}
carriers, err := guestCart.EstimateShippingCarrier(shippingAddr)
API Coverage
Products API
CreateOrReplaceProduct()- Create or update productsGetProductBySKU()- Retrieve product detailsUpdateProductStockItemBySKU()- Update inventory- Support for all product types
Categories API
CreateCategory()- Create categoriesGetCategoryByID()- Retrieve category detailsGetCategoriesList()- List all categoriesAssignProductsToCategoryByID()- Manage product assignments
Attributes API
CreateAttribute()- Create product attributesGetAttributeByCode()- Retrieve attribute detailsAddOption()- Add dropdown options- Attribute set and group management
Cart API
- Guest and customer cart support
- Add/remove items
- Shipping and payment estimation
- Order placement
Orders API
GetOrderByIncrementID()- Retrieve ordersUpdateOrderEntity()- Update order statusAddOrderComment()- Add order notes
Project Structure
go-m2rest/
├── *.go # Main library files
├── tests/ # Test files
│ ├── functional_test.go
│ ├── advanced_product_test.go
│ └── test_config.go
├── scripts/ # Utility scripts
│ ├── bulk_product_update.go
│ └── run_bulk_update.sh
├── .env.example # Example configuration
└── README.md # This file
Error Handling
The library provides structured error types. HTTP errors carry a typed *APIError (status code, endpoint, response body truncated to 500 bytes) and still match the historical sentinels via errors.Is:
product, err := magento2.GetProductBySKU("non-existent", client)
if err != nil {
if errors.Is(err, magento2.ErrNotFound) {
// Handle not found case
}
var apiErr *magento2.APIError
if errors.As(err, &apiErr) {
log.Printf("status=%d endpoint=%s body=%s", apiErr.StatusCode, apiErr.Endpoint, apiErr.Body)
}
}
Logging
The library uses zerolog for structured logging, but is silent by default: importing the package no longer installs a console writer on the global zerolog logger (this used to hijack the logging setup of importing applications). To see logs:
// Route the library's logs into your own zerolog logger
magento2.SetZeroLogger(myLogger)
// Or explicitly enable a debug-level console logger on stderr
magento2.EnableDebugLogging()
// Back to silent
magento2.DisableDebugLogging()
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
Development Setup
# Clone the repository
git clone https://github.com/florinel-chis/go-m2rest.git
cd go-m2rest
# Install dependencies
go mod download
# Run tests
go test ./...
# Run linter (optional)
golangci-lint run
License
This project is licensed under the MIT License.
Support
For issues, feature requests, or questions:
Changelog
Recent Updates
- 2026-08-10: Catalog sync read API (ctx-first pagination/iteration helpers), context support, default timeouts, 429/
Retry-Afteraware retries, typedAPIError, no-op logger by default (no more global zerolog hijack),FlexBool,WrappingAddPrintedCardfix,StoreConfig.BasePath— see CHANGELOG.md - 2025-01-15: Updated to Go 1.25+ with latest dependency versions
- Go toolchain: 1.25.1
- Updated all dependencies to latest stable versions
- golang.org/x/net: v0.47.0
- golang.org/x/sys: v0.38.0
- mattn/go-colorable: v0.1.14
- mattn/go-isatty: v0.0.20
- Verified no breaking changes
- All code compiles and passes quality checks
- Added support for Go 1.21+ features
- Migrated to resty v2 for better performance
- Added structured logging with zerolog
- Improved test coverage and organization
- Added bulk operations utilities
- Enhanced error handling with wrapped errors
Build robust Magento 2 integrations with modern Go!