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.
- 🎯 Canonical Import Paths: Single import path that works in development and production
- 🔄 go.work Overlays: Seamless transition between local development and published modules
- 🏢 Organization-Wide Catalog: Centralized API discovery across all teams
- 🚀 Multi-Format Support: Protocol Buffers, OpenAPI, Avro, JSON Schema, Parquet
- 🔍 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
APX implements a two-repository pattern:
- Canonical Repository (
github.com/<org>/apis): Single source of truth for all published APIs - 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
replacedirectives or import rewrites - Clean dependency management via
go.workoverlays
See the Quick Start Guide for a comprehensive walkthrough.
# 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=apisCreates:
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/
# In your application repository
cd /path/to/your-app
# Initialize app structure
apx init app internal/apis/proto/payments/ledger
# Lint your schema
apx lint internal/apis/proto/payments/ledger
# Check for breaking changes
apx breaking internal/apis/proto/payments/ledger
# Publish to canonical repo
apx publish --module-path=internal/apis/proto/payments/ledger# Search for APIs
apx search payment
# Add dependency
apx add proto/payments/ledger/[email protected]
# 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 published module
apx unlink proto/payments/ledger/v1brew install infobloxopen/tap/apxDownload the latest release from GitHub Releases for your platform.
go install github.com/infobloxopen/apx/cmd/apx@latestAPX integrates with format-specific tooling:
# Install all required tools
curl -sSL https://raw.githubusercontent.com/infobloxopen/apx/main/scripts/install-tools.sh | bashOr install individually:
- buf - Protocol Buffer linting and breaking change detection
- spectral - OpenAPI linting (optional)
- oasdiff - OpenAPI breaking changes (optional)
Bootstrap a canonical API repository.
apx init canonical --org=myorg --repo=apisFlags:
--org: Organization name (required)--repo: Repository name (required)--skip-git: Skip git initialization--non-interactive: Skip interactive prompts
Bootstrap an application repository for schema authoring.
apx init app internal/apis/proto/payments/ledgerFlags:
--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
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 formatCheck for breaking changes.
apx breaking internal/apis/proto/payments
apx breaking --format=openapiPublish schema module to canonical repository.
apx publish --module-path=internal/apis/proto/payments/ledger
apx publish --module-path=... [email protected]:org/apis.git
apx publish --module-path=... --base-branch=developFlags:
--module-path: Path to module in app repo (required)--canonical-repo: Canonical repository URL--base-branch: Target branch (default: main)
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.yamlAdd a schema dependency.
apx add proto/payments/ledger/[email protected]
apx add proto/users/profile/v1 # Uses latestUpdates both apx.yaml and apx.lock files.
Generate client code from dependencies.
apx gen go # Generate Go code
apx gen python # Generate Python code
apx gen java # Generate Java codeGenerated structure:
/internal/gen/
├── go/
│ └── proto/payments/[email protected]/
├── python/
│ └── proto/payments/ledger/
└── java/
└── proto/payments/ledger/
Note: /internal/gen/ is git-ignored. Never commit generated code.
Synchronize go.work with active Go overlays.
apx syncRegenerates go.work to include all overlays in /internal/gen/go/.
Remove overlay and switch to published module.
apx unlink proto/payments/ledger/v1Removes overlay from /internal/gen/ and updates go.work.
Generated by apx init app:
kind: proto
module: payments.ledger.v1
org: myorg
version: v1Pinned dependency versions (generated by apx add):
dependencies:
proto/payments/ledger/v1:
repo: github.com/myorg/apis
ref: v1.2.3
modules:
- proto/payments/ledger/v1API 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- Generate overlay:
apx gen gocreates/internal/gen/go/proto/payments/[email protected]/ - go.work magic:
apx syncupdatesgo.workto map canonical path to local overlay - Your code imports:
import "github.com/myorg/apis/proto/payments/ledger/v1" - Go resolves: Via
go.work, imports resolve to your local overlay
- Remove overlay:
apx unlink proto/payments/ledger/v1 - Add published module:
go get github.com/myorg/apis/proto/payments/ledger/[email protected] - Imports unchanged: Same
import "github.com/myorg/apis/proto/payments/ledger/v1" - Go resolves: From published module in
go.mod
No import rewrites. No replace directives. It just works.
/internal/gen/
├── go/ # Go overlays
│ ├── proto/payments/[email protected]/
│ └── proto/users/[email protected]/
├── 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
--config <file>: Specify config file (default:apx.yaml)--verbose: Enable verbose output--quiet: Suppress output--json: Output in JSON format (planned)--no-color: Disable colored output
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: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Install APX
run: go install github.com/infobloxopen/apx/cmd/apx@latest
- name: Lint Schemas
run: apx lint internal/apis
- name: Check Breaking Changes
run: apx breaking internal/apis
publish:
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: Setup Go
uses: actions/setup-go@v5
with:
go-version: '1.24'
- name: Install APX
run: go install github.com/infobloxopen/apx/cmd/apx@latest
- name: Publish to Canonical Repo
run: |
apx publish --module-path=internal/apis/proto/payments/ledger \
[email protected]:myorg/apis.git
env:
GIT_SSH_COMMAND: "ssh -i ${{ secrets.DEPLOY_KEY }}"📚 Full Documentation - Complete documentation hosted on GitHub Pages
- 📖 Quick Start Guide - Complete walkthrough
- 🏗️ Canonical Repository Structure
- 📦 Dependency Management
- 🔧 Interactive Init Guide
- 🚀 Publishing Guide
- 🔧 CLI Reference
- ❓ FAQ & Troubleshooting
- ✅ 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)
- ✅ Publishing workflow (git subtree + PR)
- ✅ Multi-language overlay structure
- 🚧 JSON output for CI automation (
--jsonflag) - 🚧 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.
0: Success1: General error2: Validation/lint errors3: Breaking changes detected4: Dependency not found5: Configuration error
make buildmake test # Unit tests
go test -run TestScript # Integration testscripts
go test ./tests/integration # Full integration testsSee CONTRIBUTING.md for development guidelines.
Licensed under the Apache License, Version 2.0. See LICENSE for details.
- 📚 Documentation - Full documentation on GitHub Pages
- 🐛 Issues - Bug reports and feature requests
- 💬 Discussions - Questions and community support