awspagination

package module
v0.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 24, 2025 License: MIT Imports: 7 Imported by: 0

README

awspagination

A golangci-lint linter that detects missing pagination handling in AWS SDK v2 List API calls.

Overview

AWS SDK for Go v2 List APIs have default result limits and require pagination handling using NextToken. This linter automatically detects missing pagination implementations to prevent bugs caused by incomplete data retrieval.

This linter is designed for integration with golangci-lint, but can also be used as a standalone command-line tool.

How It Works

This linter detects missing pagination handling by analyzing your code in three steps:

1. Identifies paginated API calls

Verifies the API call is from AWS SDK v2 by checking the package path (github.com/aws/aws-sdk-go-v2/service/...).

Then checks if the response type has pagination token fields:

  • Standard fields (checked for all services): NextToken, NextMarker, Marker, NextContinuationToken, ContinuationToken, NextPageToken, NextPageMarker
  • Service-specific fields: LastEvaluatedKey (DynamoDB), Position (API Gateway), IsTruncated/NextRecordName/NextRecordType/NextRecordIdentifier (Route53)

See Detected Pagination Token Fields for the complete list with service details.

Uses Go's type system to automatically work with any AWS service without maintaining a service list.

2. Looks for pagination handling patterns

Within the same function, searches for either:

  • Manual loop: Accesses pagination token field (e.g., result.NextToken)
  • Paginator: Uses NewXXXPaginator, HasMorePages(), or NextPage()
3. Reports if pagination is missing

If a paginated API call is found without any pagination handling pattern in the same function, a warning is reported.

Important: This linter only checks within the same function scope. If you handle pagination in a separate helper function or wrapper library, use //nolint:awspagination to suppress the warning.

Installation & Configuration

With golangci-lint

There are two integration methods available:

Add to your .golangci.yml:

linters-settings:
  custom:
    awspagination:
      path: github.com/koh-sh/awspagination
      description: Detects missing pagination handling in AWS SDK v2 List API calls
      original-url: https://github.com/koh-sh/awspagination
  awspagination:
    # Add custom pagination token field names (optional)
    custom-fields:
      - MyToken
      - CustomNextToken
    # Include test files in analysis (optional, default: false)
    include-tests: false

linters:
  enable:
    - awspagination
Method 2: Module Plugin

Add to your .golangci.yml:

linters-settings:
  custom:
    awspagination:
      path: github.com/koh-sh/awspagination
      type: "module"
      description: Detects missing pagination handling in AWS SDK v2 List API calls
      original-url: https://github.com/koh-sh/awspagination
      settings:
        custom-fields: ["MyToken", "CustomNextToken"]
        include-tests: true

linters:
  enable:
    - awspagination

Note: Both methods provide the same functionality. Method 1 (direct integration) is recommended for simplicity. Method 2 (module plugin) is useful if you need advanced plugin features.

As a standalone tool
# Installation
go install github.com/koh-sh/awspagination/cmd/awspagination@latest

# Basic usage
awspagination ./...

# With custom pagination token fields
awspagination -custom-fields=MyToken,CustomNextToken ./...

# Include test files
awspagination -include-tests ./...

Configuration Options

Custom Token Fields

Add custom pagination token field names in addition to the default fields.

Use case: Your project uses custom response types with non-standard pagination field names.

Default fields: See Detected Pagination Token Fields for the complete list.

Include Test Files

Analyze test files (*_test.go) in addition to regular source files.

Default: false (test files are excluded from analysis)

Use case: Detect missing pagination handling in test helper functions or test code that makes real API calls.

golangci-lint configuration:

linters-settings:
  awspagination:
    include-tests: true

Examples

❌ Bad: No pagination handling
func bad() {
    client := ecs.NewFromConfig(cfg)
    result, _ := client.ListTasks(ctx, &ecs.ListTasksInput{})
    // Warning: missing pagination handling for AWS SDK List API call
    for _, task := range result.TaskArns {
        fmt.Println(task)
    }
}
✅ Good: Manual loop with NextToken
func good1() {
    client := ecs.NewFromConfig(cfg)
    input := &ecs.ListTasksInput{}

    for {
        result, err := client.ListTasks(ctx, input)
        if err != nil {
            break
        }

        for _, task := range result.TaskArns {
            fmt.Println(task)
        }

        if result.NextToken == nil {
            break
        }
        input.NextToken = result.NextToken
    }
}
✅ Good: Using Paginator
func good2() {
    client := ecs.NewFromConfig(cfg)
    input := &ecs.ListTasksInput{}

    paginator := ecs.NewListTasksPaginator(client, input)
    for paginator.HasMorePages() {
        page, err := paginator.NextPage(ctx)
        if err != nil {
            break
        }

        for _, task := range page.TaskArns {
            fmt.Println(task)
        }
    }
}
✅ Good: Intentionally limited (using nolint)
func good3() {
    client := ecs.NewFromConfig(cfg)
    input := &ecs.ListTasksInput{
        MaxResults: aws.Int32(10),
    }

    //nolint:awspagination // Only need first 10 results
    result, _ := client.ListTasks(ctx, input)
    for _, task := range result.TaskArns {
        fmt.Println(task)
    }
}

Supported

  • SDK Version: AWS SDK for Go v2 only (github.com/aws/aws-sdk-go-v2)
  • Test Files: Excluded by default (use -include-tests flag to include)
Detected Pagination Token Fields
Field Name Scope Services/Usage
NextToken All Services Most common - ECS, EC2, Lambda, etc. (100+ services)
NextMarker All Services S3 ListObjects, EFS, ELB, ELBv2, KMS, Lambda, Route53, CloudFront
Marker All Services IAM, RDS, DMS, ElastiCache, Neptune, Redshift
NextContinuationToken All Services S3 ListObjectsV2
ContinuationToken All Services S3 ListObjectsV2 (input echo)
NextPageToken All Services CostExplorer, ServiceCatalog
NextPageMarker All Services Route53Domains
LastEvaluatedKey DynamoDB Query, Scan, etc.
Position API Gateway GetRestApis, GetResources, etc.
IsTruncated / NextRecordName / NextRecordType / NextRecordIdentifier Route53 ListResourceRecordSets - any field indicates pagination

All Services fields are checked for all AWS services. DynamoDB, API Gateway, and Route53 fields are only checked for their respective services.

Development

Run tests
make test
Build
make build
Test on your code
./awspagination ./your-project/...

Documentation

Index

Constants

View Source
const Doc = `` /* 238-byte string literal not displayed */

Variables

View Source
var Analyzer = &analysis.Analyzer{
	Name:     "awspagination",
	Doc:      Doc,
	Run:      run,
	Requires: []*analysis.Analyzer{inspect.Analyzer},
}

Analyzer is the awspagination analyzer. It can be used standalone or integrated into golangci-lint.

For golangci-lint integration, this analyzer requires LoadModeTypesInfo because it uses pass.TypesInfo to check types.

Functions

func New

func New(settings any) ([]*analysis.Analyzer, error)

New creates a new analyzer instance for golangci-lint module plugin integration. This function is called when the analyzer is loaded as a module plugin. It decodes settings from YAML configuration and applies them to the analyzer.

For direct integration via Analyzer.Flags, this function is not used. The two integration methods are mutually exclusive: - Module plugin: Uses this New function with Settings from YAML - Direct integration: Uses Analyzer.Flags with command-line flags

Example YAML configuration:

linters-settings:
  custom:
    awspagination:
      type: "module"
      settings:
        custom-fields: ["MyToken", "CustomNextToken"]
        include-tests: true

Types

type Config

type Config struct {
	// CustomTokenFields are additional pagination token field names to check.
	// These are added to the default fields, not replacing them.
	CustomTokenFields stringSliceFlag

	// IncludeTests determines whether to analyze test files (*_test.go).
	// Default is false (test files are excluded from analysis).
	IncludeTests bool
}

Config holds the configuration for the analyzer. This type is exported to support future golangci-lint module plugin integration, where settings are decoded from YAML using mapstructure (which requires exported fields). For current direct integration via Analyzer.Flags, the export is not strictly necessary, but maintaining it provides forward compatibility.

type Settings

type Settings struct {
	// CustomFields are additional pagination token field names to check.
	// These are added to the default fields, not replacing them.
	// Example YAML: custom-fields: ["MyToken", "CustomNextToken"]
	CustomFields []string `json:"custom-fields" mapstructure:"custom-fields"`

	// IncludeTests determines whether to analyze test files (*_test.go).
	// Default is false (test files are excluded from analysis).
	// Example YAML: include-tests: true
	IncludeTests bool `json:"include-tests" mapstructure:"include-tests"`
}

Settings holds the configuration for golangci-lint module plugin integration. This struct is used when the analyzer is loaded as a module plugin, where settings are decoded from YAML configuration files using mapstructure. For direct integration via Analyzer.Flags, use the Config struct instead.

Directories

Path Synopsis
cmd
awspagination command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL