SOAJS middleware for Golang services. This package provides seamless integration between your Go REST services and the SOAJS (Service Oriented Architecture JavaScript) framework, enabling registry management, request context handling, and multi-tenancy support.
- Features
- Requirements
- Installation
- Quick Start
- Usage
- Configuration
- Environment Variables
- Development
- CI/CD
- Documentation
- License
- Registry Management: Automatic service registry synchronization with SOAJS
- Auto-reload: Configurable automatic registry reloading
- Multi-tenancy: Built-in tenant and application context handling
- Request Context: Access tenant, user (URAC), device, and geo information per request
- Database Management: Access to core and tenant meta databases through registry
- Resource Discovery: Service and resource lookup capabilities
- HTTP Middleware: Easy integration with standard Go HTTP handlers
- Go 1.21 or higher
- Go modules enabled
- SOAJS infrastructure (Controller, Registry API)
go get github.com/soajs/soajs.golangpackage main
import (
"context"
"log"
"net/http"
soajsgo "github.com/soajs/soajs.golang"
)
func main() {
ctx := context.Background()
// Initialize registry
registry, err := soajsgo.New(ctx, "myservice", "dev", "service", true)
if err != nil {
log.Fatal(err)
}
// Create handler
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Access SOAJS context data
soaData := r.Context().Value(soajsgo.SoajsKey).(soajsgo.ContextData)
w.Write([]byte("Hello from " + soaData.Tenant.Code))
})
// Apply middleware
http.Handle("/", registry.Middleware(handler))
log.Fatal(http.ListenAndServe(":8080", nil))
}Complete working examples are available in the examples directory:
- basic_service.go - Full microservice using standard
net/http - gin_service.go - Microservice using the Gin Web Framework
Each example demonstrates:
- Service initialization and configuration
- Middleware integration
- Accessing SOAJS context data (tenant, user, device, geo)
- Database and service discovery
- Custom registry configuration
- Health checks and graceful shutdown
See the examples README for detailed documentation and usage instructions.
Create a registry connection using service name, environment code, and service type:
import (
"context"
soajsgo "github.com/soajs/soajs.golang"
)
ctx := context.Background()
// Parameters: context, serviceName, envCode, serviceType, autoReload
registry, err := soajsgo.New(ctx, "myservice", "dev", "service", true)
if err != nil {
log.Fatal(err)
}Initialize registry from a configuration struct:
config := soajsgo.Config{
ServiceName: "myservice",
ServiceGroup: "mygroup",
ServicePort: 8080,
ServiceIP: "127.0.0.1",
Type: "service",
ServiceVersion: "1",
// ... additional config fields
}
registry, err := soajsgo.NewFromConfig(ctx, config)
if err != nil {
log.Fatal(err)
}Extract SOAJS data from the request context:
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
soaData := r.Context().Value(soajsgo.SoajsKey).(soajsgo.ContextData)
// Access tenant information
tenantCode := soaData.Tenant.Code
tenantId := soaData.Tenant.ID
// Access user information (URAC)
if soaData.Urac != nil {
username := soaData.Urac.Username
userId := soaData.Urac.ID
}
// Access device and geo information
device := soaData.Device
geo := soaData.Geo
// Access registry for databases and services
registry := soaData.Reg
})The registry provides several methods for accessing databases, services, resources, and custom configurations:
// Get a database by name
db, err := registry.Database("mydb")
if err == nil {
prefix := db.Prefix
servers := db.Servers
}
// Get all databases
dbs, err := registry.Databases()
// Get a service by name
service, err := registry.Service("myservice")
if err == nil {
port := service.Port
host := service.Host
}
// Get a resource by name
resource, err := registry.Resource("myresource")
// Get a specific custom registry by name
custom, err := registry.GetCustom("myCustom")
if err == nil {
customReg := custom.(*soajsgo.CustomRegistry)
value := customReg.Value
locked := customReg.Locked
}
// Get all custom registries
allCustom, err := registry.GetCustom("")
if err == nil {
customRegistries := allCustom.(soajsgo.CustomRegistries)
for name, customReg := range customRegistries {
// Access custom registry data
fmt.Println(name, customReg.Value)
}
}
// Manually reload registry
err = registry.Reload()The Config struct supports the following fields:
type Config struct {
ServiceName string // Service name (required)
ServiceGroup string // Service group (required)
ServicePort int // Service port (required)
ServiceIP string // Service IP address
Type string // Service type: "service" or "daemon" (required)
ServiceVersion string // Service version (required)
SubType string // Service subtype
Description string // Service description
Oauth bool // OAuth enabled
Urac bool // URAC enabled
UracProfile bool // URAC profile enabled
UracACL bool // URAC ACL enabled
UracConfig bool // URAC config enabled
UracGroupConfig bool // URAC group config enabled
TenantProfile bool // Tenant profile enabled
ProvisionACL bool // Provision ACL enabled
ExtKeyRequired bool // External key required
RequestTimeout int // Request timeout
RequestTimeoutRenewal int // Request timeout renewal
Awareness bool // Awareness enabled
Maintenance Maintenance // Maintenance configuration
}The following environment variables are required:
SOAJS_ENV: Environment code (e.g., "dev", "staging", "production")SOAJS_REGISTRY_API: Registry API endpoint (e.g., "http://controller:5000")SOAJS_DEPLOY_MANUAL: Manual deployment flag ("true" or "false")
Example:
export SOAJS_ENV=dev
export SOAJS_REGISTRY_API=http://localhost:5000
export SOAJS_DEPLOY_MANUAL=truego test -v ./...go test -v -covermode=count -coverprofile=coverage.out ./...
go tool cover -html=coverage.outThis project uses golangci-lint for code quality checks:
# Install golangci-lint
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Run linter
golangci-lint run --config .golangci.yml# Format code
gofmt -w .
# Organize imports
goimports -w .This project uses Travis CI for continuous integration, testing against:
- Go 1.21.x
- Go 1.22.x
- Go 1.23.x
Each build runs:
- Linting with golangci-lint v1.64.8
- Unit tests with coverage reporting
- Coverage reports to Coveralls
For more information about SOAJS:
Contributions are welcome! Please ensure:
- All tests pass
- Code is properly formatted (gofmt)
- Linting passes (golangci-lint)
- Coverage is maintained or improved
Copyright SOAJS All Rights Reserved.
Use of this source code is governed by an Apache license that can be found in the LICENSE file at the root of this repository.