Massive Go Client

repository·master·Indexed 41 days ago

https://github.com/massive-com/client-go

Official SDK for accessing Massive (formerly Polygon.io) REST and WebSocket APIs. Built for high-performance financial data access using Go generics, it features a generated REST client with automatic pagination and tracing, and a WebSocket client with automatic reconnection and re-subscription.

Tokens
4.3K
Snippets
17
Records
21
Agent score
51%

What's inside Massive

  1. Enable automatic pagination in REST client

    master

    When making REST requests, you can enable automatic pagination by passing rest.WithPagination(true) to the client constructor. This allows you to use an iterator to seamlessly traverse through multiple pages of results by following the next_url automatically.

    c := rest.NewWithOptions("YOUR_API_KEY",
    	rest.WithPagination(true),
    )
    
    // After making a request:
    iter := rest.NewIteratorFromResponse(c, resp)
    for iter.Next() {
    	item := iter.Item()
    	fmt.Printf("%+v\n", item)
    }
    if err := iter.Err(); err != nil {
    	// handle error
    }
  2. Customize public Go method names

    master

    The public Go method names for the REST client are determined by the mapping in rest/scripts/operation-mappings.js. This file maps OpenAPI operationId values to specific Go method names.

    Warning: This file is language-specific. Do not attempt to share these mappings with other SDKs or 'fix' entries here, as changing these mappings will rename the public functions in the Go SDK.

  3. Understand the REST client generation pipeline steps

    master

    The scripts/generate.sh orchestrator performs the following steps in order:

    1. Pull the spec: rest/scripts/pull_spec.js downloads the spec from https://api.massive.com/openapi, removes draft paths, forces a single default tag, and applies operationId → method-name renames based on rest/scripts/operation-mappings.js. The resulting spec is saved to rest/scripts/openapi.json.
    2. Pre-process: A jq pass converts invalid type: number + format: int32 schemas to type: integer.
    3. Generate: oapi-codegen (configured via rest/scripts/oapi-codegen.yaml) generates the file rest/gen/client.gen.go. All generated code is isolated to this single file.
    4. Post-process: rest/scripts/fix-go-clashes.js resolves single-letter JSON field name clashes (e.g., renaming P/p to AskPrice) and runs gofmt.
  4. Quickstart: Set up a Massive Go project

    master

    To start using the Massive Go client, initialize a new Go module and install the dependencies. You can use the MASSIVE_API_KEY environment variable to avoid hardcoding your credentials.

    1. Create and enter a project directory:
      mkdir myproject && cd myproject
    2. Initialize the module:
      go mod init example
    3. Set your API key:
      export MASSIVE_API_KEY="<your_api_key>" # mac/linux
      xset MASSIVE_API_KEY "<your_api_key>"   # windows
    4. Download dependencies:
      go mod tidy
    mkdir myproject && cd myproject
    go mod init example
    export MASSIVE_API_KEY="<your_api_key>
    go mod tidy
  5. Regenerate the REST client via the generation pipeline

    master

    The REST client is generated from an OpenAPI specification. To regenerate the client locally, run the orchestration script. This process pulls the latest spec from https://api.massive.com/openapi, applies renames to ensure consistent Go method names, and uses oapi-codegen to produce the client code.

    Important Note: Only the REST client is generated. The WebSocket client (websocket/) and the REST helpers (rest/client.go, rest/iterator.go) are hand-written and are never touched by the generation process.

    bash scripts/generate.sh
  6. Debug REST requests with Trace mode

    master

    To troubleshoot query parameters, authentication, or rate limits, enable trace mode during client initialization using rest.WithTrace(true). This will print clean output for every request, including the Request URL, Request Headers, and Response Headers.

    c := rest.NewWithOptions("YOUR_API_KEY",
    	rest.WithTrace(true),
    )
  7. Use the REST API Client

    master

    The REST client is used to fetch data from Massive.com. It requires Go 1.18+ due to the use of generics. You can create a client using rest.NewWithOptions to configure features like tracing and automatic pagination.

    To use the client, import github.com/massive-com/client-go/v3/rest and github.com/massive-com/client-go/v3/rest/gen. Most endpoints provide *WithResponse methods that return both the response object and an error.

    import (
    	"context"
    	"github.com/massive-com/client-go/v3/rest"
    	"github.com/massive-com/client-go/v3/rest/gen"
    )
    
    func main() {
    	c := rest.NewWithOptions("YOUR_API_KEY",
    		rest.WithTrace(false),
    		rest.WithPagination(true),
    	)
    	ctx := context.Background()
    
    	params := &gen.GetStocksAggregatesParams{
    		Adjusted: rest.Ptr(true),
    		Sort: "asc",
    		Limit: rest.Ptr(120),
    	}
    
    	resp, err := c.GetStocksAggregatesWithResponse(
    		ctx,
    		"AAPL",
    		1,
    		"day",
    		"2026-02-16",
    		"2026-02-20",
    		params,
    	)
    	if err != nil {
    		// handle error
    	}
    
    	if err := rest.CheckResponse(resp); err != nil {
    		// handle error
    	}
    }
  8. Regenerate the REST client locally

    master

    If you need to regenerate the client from a local OpenAPI spec, you can use the provided generation script.

    Prerequisites:

    • Go 1.21+
    • Node.js 18+
    • jq

    Commands:

    bash scripts/generate.sh
    go build ./... && go test ./...

    If you do not have the toolchain installed, you can use Docker to run the generation in a matching environment (Go 1.24 + Node 22 + jq):

    docker run --rm -v "$PWD":/src -w /src golang:1.24-bookworm bash -c '
      apt-get update && apt-get install -y jq curl >/dev/null &&
      curl -fsSL https://deb.nodesource.com/setup_22.x | bash - >/dev/null &&
      apt-get install -y nodejs >/dev/null &&
      bash scripts/generate.sh'
  9. Use the WebSocket Client for real-time data

    master

    The WebSocket client provides a streaming connection to Massive.com. It features automatic reconnection and automatic re-subscription to previously set topics upon reconnection.

    1. Import github.com/massive-com/client-go/v3/websocket and github.com/massive-com/client-go/v3/websocket/models.
    2. Create a client with massivews.New(massivews.Config{...}).
    3. Call c.Connect() to establish the connection.
    4. Use c.Subscribe(topic, ...) to start receiving data.
    5. Listen to c.Output() for data messages and c.Error() for fatal errors.
    import (
        massivews "github.com/massive-com/client-go/v3/websocket"
        "github.com/massive-com/client-go/v3/websocket/models"
    )
    
    // ... setup client ...
    if err := c.Subscribe(massivews.StocksTrades, "TSLA", "GME"); err != nil {
        log.Fatal(err)
    }
    
    for {
        select {
        case err := <-c.Error():
            log.Fatal(err)
        case out, more := <-c.Output():
            if !more {
                return
            }
            switch out.(type) {
            case models.EquityAgg:
                log.Print(out)
            case models.EquityTrade:
                log.Print(out)
            }
        }
    }
  10. Reference the generation pipeline files

    master

    Use the following table to identify the role of each file in the generation process:

    FileRole
    scripts/generate.shThe single orchestrator (this pipeline).
    rest/scripts/pull_spec.jsDownload + filter + rename the spec.
    rest/scripts/operation-mappings.jsOwns the public Go method names (operationId → name).
    rest/scripts/oapi-codegen.yamloapi-codegen config (package gen, output gen/client.gen.go).
    rest/scripts/fix-go-clashes.jsPost-process single-letter field clashes + gofmt.
    rest/scripts/analyze-field-clashes.jsStandalone diagnostic — not part of the pipeline.
    rest/scripts/generate-go-examples.jsStandalone example-snippet generator — not part of the pipeline.
  11. Handle fatal errors via the Error channel

    master

    The Error() <-chan error method returns a channel that receives fatal errors. A fatal error (such as an auth_failed status message) will cause the client to push the error to this channel and close the connection.

    go func() {
        for err := range client.Error() {
            log.Fatalf("Fatal WebSocket error: %v", err)
        }
    }()