Strait Docs
SDKs

Go SDK with functional options, typed errors, and full API coverage.

The Go SDK (github.com/strait-dev/go-sdk) uses the functional options pattern and provides full API coverage across 5 packages.

Installation

go get github.com/strait-dev/go-sdk

Client Creation

import strait "github.com/strait-dev/go-sdk"

client, err := strait.NewClientFromFile(nil)

See Configuration for strait.json schema and options.

You can specify a custom directory or explicit path:

// Custom directory
client, err := strait.NewClientFromFile([]strait.ConfigFileOption{
    strait.WithConfigDir("/path/to/project"),
})

// Explicit path
client, err := strait.NewClientFromFile([]strait.ConfigFileOption{
    strait.WithConfigPath("/path/to/config.json"),
})

From environment variables

// Reads STRAIT_BASE_URL, STRAIT_API_KEY, STRAIT_AUTH_TYPE, STRAIT_TIMEOUT_MS
client, err := strait.NewClientFromEnv()

Inline with options

client := strait.NewClient(
    strait.WithBaseURL("https://api.strait.dev"),
    strait.WithAPIKey("sk_live_..."),
    strait.WithTimeout(5000),
)

Client options

OptionDescription
WithBaseURL(url)API base URL (trailing slashes stripped)
WithBearerToken(token)Bearer token auth
WithAPIKey(key)API key auth
WithRunToken(token)Run token auth
WithAuth(auth)Set auth mode directly
WithDefaultHeaders(h)Headers sent with every request
WithTimeout(ms)Timeout in milliseconds (default: 30000)
WithHTTPClient(doer)Custom HTTPDoer implementation
WithMiddleware(mw...)Request/response/error hooks

Calling Operations

Operations are organized into service packages under operations/:

import (
    "context"
    strait "github.com/strait-dev/go-sdk"
    "github.com/strait-dev/go-sdk/operations"
)

client, _ := strait.NewClientFromFile(nil)
jobs := operations.NewJobsService(client)

// List jobs
list, err := jobs.List(ctx, map[string]string{"project_id": "proj_1"})

// Create a job
created, err := jobs.Create(ctx, map[string]any{
    "name":         "Sync Inventory",
    "slug":         "sync-inventory",
    "project_id":   "proj_1",
    "endpoint_url": "https://worker.example.com/run",
})

// Trigger a job
run, err := jobs.Trigger(ctx, "job_abc", map[string]any{
    "payload": map[string]any{"sku": "ABC-123"},
})

Available services

NewJobsService, NewRunsService, NewWorkflowsService, NewWorkflowRunsService, NewDeploymentsService, NewEnvironmentsService, NewSecretsService, NewAPIKeysService, NewWebhooksService, NewEventTriggersService, NewEventSourcesService, NewBatchOperationsService, NewStatsService, NewAnalyticsService, NewLogDrainsService, NewSDKRunsService, NewRBACService, NewJobGroupsService, NewHealthService

Authoring DSL

Defining jobs

import "github.com/strait-dev/go-sdk/authoring"

type Payload struct {
    SKU string `json:"sku"`
}

job := authoring.DefineJob(authoring.JobOptions[Payload]{
    Name:        "Sync Inventory",
    Slug:        "sync-inventory",
    EndpointURL: "https://worker.dev/jobs/sync",
    ProjectID:   "proj_1",
    Run: func(p Payload, ctx authoring.RunContext) (any, error) {
        return syncInventory(p.SKU)
    },
})

job.Register(ctx, client, "")
job.Trigger(ctx, client, authoring.TriggerJobInput[Payload]{
    Payload: Payload{SKU: "ABC-123"},
})

Defining workflows

wf := authoring.DefineWorkflow(authoring.WorkflowOptions[Payload]{
    Name:      "Order Pipeline",
    Slug:      "order-pipeline",
    ProjectID: "proj_1",
    Steps: []authoring.Step{
        authoring.Job("validate", "job_validate"),
        authoring.Job("charge", "job_charge", authoring.DependsOn("validate")),
        authoring.Approval("review", func(a *authoring.ApprovalStep) {
            a.DependsOn = []string{"charge"}
        }),
    },
})
// DAG is validated at definition time

Composition Helpers

import "github.com/strait-dev/go-sdk/composition"

// Retry with backoff
result, err := composition.WithRetry(ctx, func() (string, error) {
    return callAPI()
}, &composition.RetryOptions{Attempts: 5, DelayMs: 100})

// Paginate
for item, err := range composition.Paginate(listFn, nil) {
    // process item
}

// Wait for run
run, err := composition.WaitForRun(ctx, getRun, getStatus, "run_123", nil)

FSM State Machines

import "github.com/strait-dev/go-sdk/fsm"

fsm.CanTransitionRun(fsm.RunExecuting, fsm.RunEventComplete)  // true
fsm.IsTerminalRunStatus(fsm.RunCompleted)                       // true

Middleware

client := strait.NewClient(
    strait.WithBaseURL("https://api.strait.dev"),
    strait.WithAPIKey("sk_live_..."),
    strait.WithMiddleware(strait.Middleware{
        OnRequest:  func(ctx strait.MiddlewareRequestContext) {
            log.Println(ctx.Method, ctx.URL)
        },
        OnResponse: func(ctx strait.MiddlewareResponseContext) {
            log.Println(ctx.Status, ctx.DurationMs, "ms")
        },
        OnError: func(ctx strait.MiddlewareErrorContext) {
            log.Println("error:", ctx.Error)
        },
    }),
)

Custom HTTP Client

Any type implementing the HTTPDoer interface can replace the default http.Client:

type HTTPDoer interface {
    Do(req *http.Request) (*http.Response, error)
}

client := strait.NewClient(
    strait.WithBaseURL("https://api.strait.dev"),
    strait.WithAPIKey("sk_live_..."),
    strait.WithHTTPClient(myCustomClient),
)

Error Handling

All errors are typed. Use errors.As to match:

import "errors"

result, err := jobs.Get(ctx, "nonexistent")
if err != nil {
    var notFound *strait.NotFoundError
    var rateLimited *strait.RateLimitedError

    switch {
    case errors.As(err, &notFound):
        fmt.Println("Not found:", notFound.Message)
    case errors.As(err, &rateLimited):
        fmt.Println("Rate limited:", rateLimited.Message)
    default:
        fmt.Println("Error:", err)
    }
}
Error typeHTTP StatusDescription
*TransportErrorNetwork failure
*DecodeErrorJSON decode failure
*ValidationErrorConfig/input validation
*UnauthorizedError401, 403Auth failure
*NotFoundError404Resource not found
*ConflictError409Duplicate/conflict
*RateLimitedError429Rate limit exceeded
*ApiErrorotherGeneric HTTP error
*TimeoutErrorPolling timeout
*DagValidationErrorInvalid workflow DAG

Packages

PackageImportDescription
straitgithub.com/strait-dev/go-sdkClient, config, errors, HTTP, middleware
authoringgithub.com/strait-dev/go-sdk/authoringDefineJob, DefineWorkflow, steps, DAG validation
compositiongithub.com/strait-dev/go-sdk/compositionResult, retry, wait, paginate, deployments
fsmgithub.com/strait-dev/go-sdk/fsmRun, workflow, step state machines
operationsgithub.com/strait-dev/go-sdk/operationsDomain services for all API endpoints
Was this page helpful?

On this page