go-fastly Go Client Library

repository·main·Indexed 41 days ago

https://github.com/fastly/go-fastly

A Go client library for interacting with the Fastly Control Plane API, providing typed structures and methods to manage Fastly services and configurations. It includes support for Realtime Stats (RTS), WAF configuration, API tokens, and various logging endpoints. The library follows Semantic Versioning and provides specialized encoding methods for JSON, JSON API, and form-encoded requests.

Tokens
4.6K
Snippets
11
Records
39
Agent score
51%

What's inside go-fastly

  1. How testing and API fixtures work in Go Fastly

    main

    Go Fastly uses go-vcr to record and replay API request fixtures. This mechanism improves the speed and portability of integration tests by using recorded YAML files instead of making live API calls every time.

    When running tests, the suite typically uses specific service IDs for Delivery, Compute, and Next-Gen WAF (NGWAF) to interact with the Fastly API. If you are a contributor without access to the official test services, you can still update or create fixtures by providing your own service IDs and API key via environment variables.

  2. How request serialization works in go-fastly

    main

    Certain Fastly Control Plane API resources (such as versionless resources on Delivery services and Next-Gen WAF workspaces) cannot be safely modified using concurrent requests. To prevent race conditions, go-fastly implements serialization for mutating operations (Create, Update, and Delete).

    There are two modes of serialization:

    1. Automatic Serialization (Default): All mutating requests are serialized globally. This is the safest mode but can degrade performance because concurrent mutations against different resources will not run in parallel.
    2. Resource-level Serialization: You can optimize performance by providing a specific 'resource ID' (e.g., a Service ID or Workspace ID). This ensures that requests targeting the same resource are serialized against each other, while requests targeting different resources can still execute in parallel.
  3. Understand Go Fastly versioning and release schedules

    main

    The module follows Semantic Versioning (SemVer):

    • Major version increment: Breaking changes (removal of functionality or incompatible changes).
    • Minor version increment: New features.
    • Patch version increment: Bug fixes that do not affect compatibility.

    Release Schedule:

    • Regular Releases: Published on the first Wednesday of each month (delayed if it falls on a US holiday).
    • Urgent Releases: Patch releases are made between regular cycles for critical or urgent bug fixes.
  4. Configure the client for Fastly Compute

    main

    Support for the Fastly Compute platform is currently in development. If you are using standard Go (not TinyGo), you can achieve a usable client by manually configuring the HTTPClient.Transport.

    Note that the go-fastly API client uses github.com/mitchellh/mapstructure internally. There are known issues regarding Go's reflect package and the maturity of TinyGo support for this library.

    client, err := fastly.NewClient("FASTLY_API_KEY")
    client.HTTPClient.Transport = fsthttp.NewTransport("fastly")
  5. Set up the go-fastly development environment

    main

    To develop on the go-fastly repository, clone the project, download the required Go modules, and use make to verify changes.

    1. Clone the repository.
    2. Download dependencies:
      go mod download
    3. Verify changes using the provided Makefile:
      make all
    $ go mod download
    $ make all
  6. Security precautions when regenerating fixtures

    main

    When regenerating fixtures, follow these two critical security rules:

    1. Use a temporary token for token-related tests: One test validates token revocation using the /tokens/self endpoint. If you run this without existing fixtures, the token provided in your environment will be revoked. Do not use a production token that is used by live applications.

    2. Redact sensitive information: Ensure all sensitive data returned by the API is redacted from the generated YAML fixtures. Specifically, when testing token creation, you may need to enter actual credentials into token_test.go. You must redact these values from both the generated fixture and the .go file before committing.

    Example of sensitive data that must be redacted:

    input := &CreateTokenInput{
    	Name:     "my-test-token",
    	Scope:    "global",
    	Username: "XXXXXXXXXXXXXXXXXXXXXX",
    	Password: "XXXXXXXXXXXXXXXXXXXXXX",
    }
  7. Implement resource-level serialization for better performance

    main

    To avoid the performance penalty of global serialization, use fastly.NewContextForResourceID to create a context containing a unique resource identifier (like a Service ID or Workspace ID). Pass this context into the Context field of your operation's Input structure.

    This allows go-fastly to group mutations by resource, enabling parallel execution for distinct resources while maintaining safety for concurrent mutations on the same resource.

    import (
    	"context"
    	"github.com/fastly/go-fastly/v17/fastly"
    )
    
    client := fastly.DefaultClient()
    serviceID := "1234abcd"
    
    // Create a context tied to the specific resource ID
    requestContext := fastly.NewContextForResourceID(context.TODO(), serviceID)
    
    // Pass the context into the Input structure
    client.CreateBackend(&fastly.CreateBackendInput {
    	ServiceID:      serviceID,
    	ServiceVersion: 5,
    	Name:           fastly.ToPointer("test"),
    	Address:        fastly.ToPointer("example.com"),
    	Context:        requestContext,
    })
  8. Update or regenerate API fixtures

    main

    To update a set of fixture files, you must first remove the existing YAML fixtures and then run a subset of tests using make test. Running the tests will cause go-vcr to recreate the deleted fixtures based on the live API responses.

    You must provide your own service IDs and API key for the tests to successfully record new data. Use the TESTARGS variable to pass flags (like -run) to the underlying go test command.

    # 1. Remove existing fixtures
    rm -r fastly/fixtures/.../*
    
    # 2. Run tests to recreate them
    make test \
      FASTLY_TEST_DELIVERY_SERVICE_ID="..." \
      FASTLY_TEST_COMPUTE_SERVICE_ID="..." \
      FASTLY_TEST_NGWAF_WORKSPACE_ID="..." \
      FASTLY_API_KEY="..." \
      TESTARGS="-run=..."
  9. Reset fixtures to default service IDs

    main

    Before submitting a pull request that includes new or updated fixtures, you must reset them to use the project's default service IDs and workspace ID. Use the following make commands to fix the fixtures for Delivery, Compute, and Next-Gen WAF respectively.

    make fix-delivery-fixtures FASTLY_TEST_DELIVERY_SERVICE_ID=<your Delivery SID>
    
    make fix-compute-fixtures FASTLY_TEST_COMPUTE_SERVICE_ID=<your Compute SID>
    
    make fix-ngwaf-fixtures FASTLY_TEST_NGWAF_WORKSPACE_ID=<your Next-Gen WAF workspace ID>
  10. Install the Go Fastly client

    main

    To use the Fastly API client in your Go project, import the github.com/fastly/go-fastly/v17/fastly module.

    Note: This client may not function correctly on the Fastly Compute platform. Support for Compute is currently on the roadmap but is not yet prioritized.

    import "github.com/fastly/go-fastly/v17/fastly"
  11. Initialize a Fastly API Client

    main

    You can create a Fastly API client using several methods depending on your authentication and endpoint requirements:

    1. DefaultClient(): The simplest way. It reads the API key from the FASTLY_API_KEY environment variable and uses the default Fastly API endpoint.
    2. NewClient(key string): Creates a client with a specific API key and uses the default endpoint (or the endpoint specified by FASTLY_API_URL).
    3. NewClientForEndpoint(key, endpoint string): Creates a client with a specific API key and a custom endpoint URL.

    Note: If an API key is not provided, the client will still initialize, but requests requiring authentication will return a 403 error.

    import "github.com/fastly/go-fastly/v17/fastly"
    
    // Option 1: Using environment variables
    client := fastly.DefaultClient()
    
    // Option 2: Providing a specific key
    client, err := fastly.NewClient("YOUR_API_KEY")
    
    // Option 3: Custom endpoint
    client, err := fastly.NewClientForEndpoint("YOUR_API_KEY", "https://api.example.com")
  12. Initialize a Realtime Stats (RTS) Client

    main

    To interact with the Fastly Realtime Stats API, use the RTSClient type. This client is specialized for realtime stats requests.

    1. NewRealtimeStatsClient(): Uses the FASTLY_API_KEY environment variable and the default realtime stats endpoint (https://rt.fastly.com).
    2. NewRealtimeStatsClientForEndpoint(token, endpoint string): Creates an RTS client with a specific token and endpoint URL.
    import "github.com/fastly/go-fastly/v17/fastly"
    
    // Using environment variables
    rtsClient := fastly.NewRealtimeStatsClient()
    
    // Using specific credentials
    rtsClient, err := fastly.NewRealtimeStatsClientForEndpoint("YOUR_TOKEN", "https://rt.fastly.com")