Skip to content

infobloxopen/apx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

184 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
APX Logo

Go Version Release License Go Report Card Documentation

apx – API Release eXperience CLI

apx is a CLI tool that implements the canonical repository pattern for API schema management. It enables organizations to centralize API schemas in a single source of truth while allowing teams to author schemas in their application repositories with canonical import paths.

Key Features

  • Canonical Import Paths: Single import path that works in development and production
  • Custom Import Roots: Decouple public API identity from Git hosting — use go.acme.dev/apis while hosting at github.com/acme/apis
  • go.work Overlays: Seamless transition between local development and released modules
  • Organization-Wide Catalog: Centralized API discovery across all teams
  • Multi-Format Support: Protocol Buffers, OpenAPI, Avro, JSON Schema, Parquet (see Format Maturity)
  • Schema Validation: Automated linting and breaking change detection
  • Code Generation: Generate client code for Go, Python, and Java
  • Policy Enforcement: Org-wide lint and breaking change policies

Architecture Overview

APX implements a two-repository pattern:

  1. Canonical Repository (github.com/<org>/apis): Single source of truth for all released APIs
  2. App Repositories: Where teams author schemas and generate code with canonical import paths

Benefits:

  • Import paths never change when switching from dev to production
  • No replace directives or import rewrites
  • Clean dependency management via go.work overlays
  • Optional import_root decouples Go import paths from Git hosting (e.g. go.acme.dev/apis)

Quick Start

See the Quick Start Guide for a comprehensive walkthrough.

1. Bootstrap Canonical Repository

# Create your organization's canonical API repository
git clone https://github.com/<org>/apis.git
cd apis

# Initialize the canonical structure
apx init canonical --org=<org> --repo=apis

Creates:

apis/
├── buf.yaml              # Org-wide lint/breaking policy
├── buf.work.yaml         # Workspace config
├── CODEOWNERS            # Per-path ownership
├── catalog/
│   └── catalog.yaml      # API discovery catalog
└── proto/                # Schema directories
    └── openapi/
    └── avro/
    └── jsonschema/
    └── parquet/

2. Author API in App Repository

# In your application repository
cd /path/to/your-app

# Initialize app structure
apx init app --org=<org> --repo=<app-repo> internal/apis/proto/payments/ledger

# Lint your schema
apx lint internal/apis/proto/payments/ledger

# Check for breaking changes
apx breaking --against=HEAD^ internal/apis/proto/payments/ledger

# Release to canonical repo
apx release prepare proto/payments/ledger/v1 --version v1.0.0 --lifecycle stable
apx release submit

3. Consume API in Another Service

# Search for APIs
apx search payment

# Add dependency
apx add proto/payments/ledger/v1@v1.2.3

# Generate code with canonical imports
apx gen go

# Your code now uses: github.com/<org>/apis/proto/payments/ledger/v1
# Works seamlessly via go.work overlay!

# When ready, switch to released module
apx unlink proto/payments/ledger/v1

Installation

Homebrew (macOS)

brew install --cask infobloxopen/tap/apx

Scoop (Windows)

scoop bucket add infobloxopen https://github.com/infobloxopen/scoop-bucket
scoop install infobloxopen/apx

Shell Installer (macOS/Linux)

curl -fsSL https://raw.githubusercontent.com/infobloxopen/apx/main/install.sh | bash

Pin a specific version or change the install directory:

curl -fsSL https://raw.githubusercontent.com/infobloxopen/apx/main/install.sh | VERSION=1.2.3 bash
curl -fsSL https://raw.githubusercontent.com/infobloxopen/apx/main/install.sh | INSTALL_DIR=/usr/local/bin bash

Download Binary

Download the latest release from GitHub Releases for your platform.

Build from Source

go install github.com/infobloxopen/apx/cmd/apx@latest

Install Tool Dependencies

APX integrates with format-specific tooling:

# Install all required tools
curl -sSL https://raw.githubusercontent.com/infobloxopen/apx/main/scripts/install-tools.sh | bash

Or install individually:

  • buf - Protocol Buffer linting and breaking change detection
  • spectral - OpenAPI linting (optional)
  • oasdiff - OpenAPI breaking changes (optional)

Command Reference

Repository Initialization

apx init canonical

Bootstrap a canonical API repository.

apx init canonical --org=myorg --repo=apis

Flags:

  • --org: Organization name (required)
  • --repo: Repository name (required)
  • --skip-git: Skip git initialization
  • --non-interactive: Skip interactive prompts

apx init app <module-path>

Bootstrap an application repository for schema authoring.

apx init app internal/apis/proto/payments/ledger

Flags:

  • --org: Organization name (required)
  • --non-interactive: Skip interactive prompts

Auto-detects format from path:

  • /proto/ -> Protocol Buffers
  • /openapi/ -> OpenAPI
  • /avro/ -> Avro
  • /jsonschema/ -> JSON Schema
  • /parquet/ -> Parquet

Schema Validation

apx lint [path]

Validate schema files for syntax and style issues.

apx lint                                  # Lint current directory
apx lint internal/apis/proto/payments    # Lint specific path
apx lint --format=proto                   # Explicit format

apx breaking [path]

Check for breaking changes.

apx breaking internal/apis/proto/payments
apx breaking --format=openapi

Releasing

APX uses a structured multi-step release pipeline (prepare -> submit -> finalize -> promote) with manifest tracking, policy checks, and immutable release records.

apx release

Structured release pipeline for CI and production workflows.

# Prepare a release (validate, build manifest)
apx release prepare proto/payments/ledger/v1 --version v1.0.0 --lifecycle stable

# Submit to canonical repo (opens PR)
apx release submit

# After PR merge, canonical CI runs finalize
apx release finalize

# Inspect current release state
apx release inspect proto/payments/ledger/v1

# List release history
apx release history proto/payments/ledger/v1

# Promote lifecycle (e.g. beta -> stable)
apx release promote proto/payments/ledger/v1 --to stable --version v1.0.0

Consumer Workflow

apx search [query]

Search for APIs in the canonical catalog.

apx search                          # List all APIs
apx search payment                  # Search by keyword
apx search --format=proto           # Filter by format
apx search --catalog=path/to/catalog.yaml

apx add <module-path>[@version]

Add a schema dependency.

apx add proto/payments/ledger/v1@v1.2.3
apx add proto/users/profile/v1              # Uses latest

Updates both apx.yaml and apx.lock files.

apx gen <language> [path]

Generate client code from dependencies.

apx gen go                    # Generate Go code
apx gen python                # Generate Python code
apx gen java                  # Generate Java code

Generated structure:

/internal/gen/
├── go/
│   └── proto/payments/ledger@v1.2.3/
├── python/
│   └── proto/payments/ledger/
└── java/
    └── proto/payments/ledger/

Note: /internal/gen/ is git-ignored. Never commit generated code.

apx sync

Synchronize go.work with active Go overlays.

apx sync

Regenerates go.work to include all overlays in /internal/gen/go/.

apx unlink <module-path>

Remove overlay and switch to released module.

apx unlink proto/payments/ledger/v1

Removes overlay from /internal/gen/ and updates go.work.

Configuration Files

apx.yaml (App Repository)

Generated by apx init app:

# import_root: go.myorg.dev/apis   # optional: custom Go import prefix

api:
  id: proto/payments/ledger/v1
  format: proto
  domain: payments
  name: ledger
  line: v1
  lifecycle: beta

source:
  repo: github.com/myorg/apis
  path: proto/payments/ledger/v1

releases:
  current: v1.0.0-beta.1

When import_root is set, Go module and import paths use the custom root instead of source.repo. For example, with import_root: go.myorg.dev/apis, the Go import path becomes go.myorg.dev/apis/proto/payments/ledger/v1.

apx.lock (App Repository)

Pinned dependency versions (generated by apx add):

dependencies:
  proto/payments/ledger/v1:
    repo: github.com/myorg/apis
    ref: v1.2.3
    modules:
      - proto/payments/ledger/v1

catalog/catalog.yaml (Canonical Repository)

API discovery catalog (auto-generated):

version: 1
org: myorg
repo: apis
modules:
  - name: proto/payments/ledger/v1
    format: proto
    description: Payment ledger API
    version: v1.2.3
    path: proto/payments/ledger/v1

How It Works: Canonical Import Paths

Development Flow

  1. Generate overlay: apx gen go creates /internal/gen/go/proto/payments/ledger@v1.2.3/
  2. go.work magic: apx sync updates go.work to map canonical path to local overlay
  3. Your code imports: import "github.com/myorg/apis/proto/payments/ledger/v1"
  4. Go resolves: Via go.work, imports resolve to your local overlay

Production Flow

  1. Remove overlay: apx unlink proto/payments/ledger/v1
  2. Add released module: go get github.com/myorg/apis/proto/payments/ledger/v1@v1.2.3
  3. Imports unchanged: Same import "github.com/myorg/apis/proto/payments/ledger/v1"
  4. Go resolves: From released module in go.mod

No import rewrites. No replace directives. It just works.

Custom Import Roots

Organizations can decouple their public Go import paths from Git hosting by setting import_root in apx.yaml:

import_root: go.acme.dev/apis

All derived Go paths then use the custom root:

Without import_root With import_root: go.acme.dev/apis
github.com/acme/apis/proto/payments/ledger go.acme.dev/apis/proto/payments/ledger
github.com/acme/apis/proto/payments/ledger/v1 go.acme.dev/apis/proto/payments/ledger/v1

The source repository remains unchanged — only the public import identity shifts. This lets organizations migrate Git hosts or use vanity domains without breaking consumer imports.

Multi-Language Support

Overlay Structure

/internal/gen/
├── go/                           # Go overlays
│   ├── proto/payments/ledger@v1.2.3/
│   └── proto/users/profile@v1.0.1/
├── python/                       # Python packages
│   ├── proto/payments/ledger/
│   └── proto/users/profile/
└── java/                         # Java packages
    ├── proto/payments/ledger/
    └── proto/users/profile/

Why language subdirectories?

  • Prevents conflicts when generating for multiple languages
  • Each language has its own namespace and structure
  • Overlay manager handles language-specific path resolution

Global Flags

  • --config <file>: Specify config file (default: apx.yaml)
  • --verbose: Enable verbose output
  • --quiet: Suppress output
  • --json: Output in JSON format
  • --no-color: Disable colored output

CI/CD Integration

GitHub Actions Example

name: API Schema Workflow

on:
  pull_request:
    paths:
      - 'internal/apis/**'

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Install APX
        uses: infobloxopen/apx@main

      - name: Lint Schemas
        run: apx lint internal/apis

      - name: Check Breaking Changes
        run: apx breaking internal/apis

  release:
    if: github.ref == 'refs/heads/main'
    needs: validate
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 0
          token: ${{ secrets.CANONICAL_REPO_TOKEN }}

      - name: Install APX
        uses: infobloxopen/apx@main

      - name: Release to Canonical Repo
        run: |
          apx release prepare proto/payments/ledger/v1 \
            --version v1.0.0 --lifecycle stable
          apx release submit
        env:
          GIT_SSH_COMMAND: "ssh -i ${{ secrets.DEPLOY_KEY }}"

Documentation

Full Documentation - Complete documentation hosted on GitHub Pages

Quick Links

Development Status

Implemented Features

  • Canonical repository initialization
  • App repository scaffolding
  • Schema validation (lint, breaking)
  • Code generation (Go, Python, Java)
  • Overlay management with go.work
  • API discovery and search
  • Dependency management (apx.lock)
  • Release workflow (PR-based canonical submission)
  • Multi-language overlay structure

Planned Features

  • Offline/air-gapped mode via apx fetch
  • GitHub Enterprise Server support
  • Performance instrumentation
  • Enhanced error messages with actionable guidance

See CHANGELOG.md for detailed release notes.

Exit Codes

  • 0: Success
  • 1: General error
  • 2: Validation/lint errors
  • 3: Breaking changes detected
  • 4: Dependency not found
  • 5: Configuration error

Development

Building

make build

Testing

make test                    # Unit tests
go test -run TestScript      # Integration testscripts
go test ./tests/integration  # Full integration tests

End-to-End Tests

The E2E test suite validates the complete APX workflow using k3d (lightweight Kubernetes) with Gitea as a git hosting simulator and testscript for test orchestration.

# Install E2E dependencies (k3d, kubectl)
make install-e2e-deps

# Run E2E tests (creates k3d cluster, deploys Gitea, runs scenarios)
make test-e2e

# Clean up any leftover E2E resources
make clean-e2e

What it tests: Canonical repo bootstrap -> schema release -> cross-repo dependencies -> breaking change detection -> git history preservation -- all against a real git server.

Requirements: Docker, ~2GB free memory, ~56 seconds runtime.

See tests/e2e/README.md for the full developer guide.

Contributing

See CONTRIBUTING.md for development guidelines.

License

Licensed under the Apache License, Version 2.0. See LICENSE for details.

Support

About

No description, website, or topics provided.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Packages

 
 
 

Contributors