Getting Started
Server SDKs
Go

Getting Started with Go and Fiber

Stanza provides a Go SDK with adapters for easy integration with popular libraries.

Install the package

$ go get github.com/StanzaSystems/sdk-go

Initialize Stanza

Import the necessary dependencies

You can initialize the Stanza Go SDK in your application by providing the approporiate imports for your use case. The simplest case imports the main library like this:

import (
	"context"
	"log"
 
	"github.com/StanzaSystems/sdk-go/stanza"
)

You can also use one of the provided adaptors for whatever framework you're working with. For example if you are using Fiber (opens in a new tab) and Zap (opens in a new tab), you can use the fiberstanza adapter. If there's an adapter you'd like to see that we don't have, you can submit a PR to add it, or send us feedback requesting one.

import (
	"context"
	"encoding/json"
 
	"github.com/StanzaSystems/sdk-go/adapters/fiberstanza"
	"github.com/gofiber/contrib/fiberzap"
	"github.com/gofiber/fiber/v2"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
)

Initialize Stanza at the root of your application

const (
	name        = "MyService"
	release     = "0.1.0"
	environment = "dev"
	debug       = true
)
 
// Create a context before initialzing Stanza (or re-use an existing one)
ctx := context.Background()
 
shutdown, stanzaInitErr := stanza.Init(ctx,
	stanza.Client{
		APIKey:      "<your Type API Key>", // API key from the Stanza UI
		Name:        name,        // the name of your service
		Release:     release,     // the release/version of your service
		Environment: environment, // the environment of your service 
	})
defer shutdown()
if stanzaInitErr != nil {
	logger.Error("stanza.init", log.Error(stanzaInitErr))
}

Leverage Stanza

Inbound Guards

Stanza inbound guards intercept a service's incoming traffic to guard that service from overload. Services with inbound guards can be configured to shed load in the Stanza UI based on multiple factors, including requests per second, CPU saturation, and memory utilization.

To use an inbound guard, register it as middleware using one of the Stanza adapters. For example, if you are using Fiber (opens in a new tab), you would use the fiberstanza middleware:

// fiber: HTTP server
app := fiber.New()
 
if stanzaInitErr == nil {
	app.Use("/", fiberstanza.Middleware("RootGuard"))
	app.Use("/login", fiberstanza.Middleware("LoginGuard"))
}

Outbound Guards

Outbound guards guard another service from overload at the calling point of your service. They are useful for managing requests to services you do not control the code for. For example, outbound guards are a great way to manage rate limiting from third parties.

To use an outbound guard, wrap the call using the Stanza API provided functions. If you have already imported an adapter (fiberstanza for example), you will have many outbound wrappers available to use (HttpGet, HttpPost, etc).

To create and configure a guard with a feature option in Stanza, follow these steps:

  1. Define the feature: First, define a variable for the feature you want to guard. For example:

    var featureGetCurrencies = "ChangeCurrency"
  2. Create the guard: Use the stanza.Guard() function to create a guard. This function takes three parameters:

    • The context (ctx)
    • A guard name (a string identifier for the guard)
    • Guard options (stanza.GuardOpt)

    Example:

    stz := stanza.Guard(ctx, guardName, stanza.GuardOpt{
        Feature: &featureGetCurrencies,
    })
  3. Handle guard errors: Check if the guard creation resulted in an error:

    if stz.Error() != nil {
        return nil, stz.Error()
    }
  4. Check if the guard is blocking: Use the Blocked() method to determine if the guard is blocking the operation:

    if stz.Blocked() {
        log.Debug("Operation blocked by Stanza")
        stz.End(stz.Failure)
        return nil, errors.New("Operation blocked by Stanza")
    }
  5. Proceed with the guarded operation: If the guard is not blocking, proceed with your operation.

  6. End the guard: After the operation, end the guard by calling the End() method with the appropriate status:

    stz.End(stz.Success) // For successful operations
    // or
    stz.End(stz.Failure) // For failed operations

Here's a complete example:

var featureGetCurrencies = "ChangeCurrency"
 
func (fe *frontendServer) getCurrencies(ctx context.Context) ([]string, error) {
    log := ctx.Value(ctxKeyLog{}).(logrus.FieldLogger)
    log.Debug("getCurrencies called")
 
    stz := stanza.Guard(ctx, "getCurrenciesGuard", stanza.GuardOpt{
        Feature: &featureGetCurrencies,
    })
    if stz.Error() != nil {
        return nil, stz.Error()
    }
 
    if stz.Blocked() {
        log.Debug("getCurrencies call blocked by Stanza")
        stz.End(stz.Failure)
        return nil, errors.New("getCurrencies call blocked by Stanza")
    }
 
    // Perform the guarded operation here
 
    stz.End(stz.Success)
    return result, nil
}

This pattern allows you to easily integrate Stanza guards into your application, controlling access to specific features and managing the flow of your operations based on Stanza's decisions.

;