Canonical Repository Structure¶
The canonical repository follows a specific directory layout that supports multiple schema formats and versioning strategies.
Complete Directory Structure¶
apis/
├── buf.yaml # org-wide lint/breaking policy
├── buf.work.yaml # workspace aggregating version dirs
├── CODEOWNERS # per-path ownership
├── catalog/
│ └── catalog.yaml # generated index of APIs/owners/tags
├── proto/ # Protocol Buffers
│ └── payments/
│ └── ledger/
│ ├── go.mod # v1 module: module github.com/<org>/apis/proto/payments/ledger
│ ├── v1/
│ │ └── ledger.proto # package <org>.payments.ledger.v1
│ └── v2/
│ ├── go.mod # v2 module: module github.com/<org>/apis/proto/payments/ledger/v2
│ └── ledger.proto # package <org>.payments.ledger.v2
├── openapi/ # OpenAPI specifications
│ └── users/
│ └── v1/
│ ├── go.mod
│ └── users.yaml
├── avro/ # Avro schemas
│ └── events/
│ └── v1/
│ ├── go.mod
│ └── user-events.avsc
├── jsonschema/ # JSON Schema definitions
│ └── config/
│ └── v1/
│ ├── go.mod
│ └── app-config.json
└── parquet/ # Parquet schemas
└── analytics/
└── v1/
├── go.mod
└── events.parquet
Key Configuration Files¶
buf.yaml (Organization-wide Policy)¶
version: v2
lint:
use: [STANDARD]
except:
- PACKAGE_DIRECTORY_MATCH # Allow flexible directory structure
breaking:
use: [FILE, WIRE]
except:
- FIELD_SAME_JSON_NAME # Allow field name changes
buf.work.yaml (Workspace Configuration)¶
CODEOWNERS (Per-API Ownership)¶
# Global fallback
* @org/api-governance
# Domain-specific ownership
/proto/payments/ @org/payments-team
/proto/users/ @org/identity-team
/openapi/gateway/ @org/platform-team
# Schema format ownership
/avro/ @org/data-engineering
/parquet/ @org/analytics-team
Versioning & Go Modules¶
Path Mapping¶
Every API has a deterministic set of coordinates derived from its canonical repo identity:
| Coordinate | Example |
|---|---|
| API ID | proto/payments/ledger/v1 |
| Source path | proto/payments/ledger/v1 |
| Proto package | myorg.payments.ledger.v1 |
| Go module (v1) | github.com/myorg/apis/proto/payments/ledger |
| Go import (v1) | github.com/myorg/apis/proto/payments/ledger/v1 |
| Go module (v2+) | github.com/myorg/apis/proto/payments/ledger/v2 |
| Go import (v2+) | github.com/myorg/apis/proto/payments/ledger/v2 |
| Git tag | proto/payments/ledger/v1/v1.2.3 |
All paths derive from the single canonical repo github.com/<org>/apis. There is no separate Go distribution repo.
Semantic Import Versioning¶
APX follows Go's semantic import versioning:
- v1 modules: No
/v1suffix in module path module github.com/<org>/apis/proto/payments/ledger- v2+ modules: Include
/vNsuffix module github.com/<org>/apis/proto/payments/ledger/v2
Directory vs Package vs Module¶
-
Directory Structure
-
Proto Package Names
-
Go Module Paths
Example go.mod Files¶
v1 module (no version suffix):
v2 module (with version suffix):
Tagging Strategy¶
Subdirectory Tags¶
APX uses subdirectory tags for each API version:
# v1 releases
proto/payments/ledger/v1/v1.0.0
proto/payments/ledger/v1/v1.2.3
# v2 releases
proto/payments/ledger/v2/v2.0.0
proto/payments/ledger/v2/v2.1.0
# Other formats
openapi/users/v1/v1.0.0
avro/events/v1/v1.5.0
Tag Protection¶
Protect tag patterns to ensure only CI creates tags:
proto/**/v*- Protocol Buffer APIsopenapi/**/v*- OpenAPI specificationsavro/**/v*- Avro schemasjsonschema/**/v*- JSON schemasparquet/**/v*- Parquet schemas
Catalog Generation¶
The catalog/catalog.yaml file is automatically generated by CI and provides searchable metadata:
version: 1
generated_at: "2024-01-15T10:30:00Z"
apis:
- path: proto/payments/ledger
kind: proto
latest_version: v1.2.3
description: "Ledger service for payment processing"
owners: ["@org/payments-team"]
tags:
- v1.0.0
- v1.1.0
- v1.2.3
- path: openapi/users
kind: openapi
latest_version: v1.0.0
description: "User management REST API"
owners: ["@org/identity-team"]
tags:
- v1.0.0
This catalog enables: - apx search functionality - API discovery and browsing - Automated documentation generation - Dependency analysis
Multi-Format Considerations¶
Format-Specific Directories¶
Each schema format has its own top-level directory:
- proto/: Protocol Buffers with buf integration
- openapi/: OpenAPI 3.0+ specifications
- avro/: Avro schema definitions
- jsonschema/: JSON Schema validation rules
- parquet/: Parquet schema definitions
Shared Tooling¶
While directories are separate, APX provides unified tooling:
# Works across all formats
apx lint # Format-specific linting
apx breaking # Format-specific breaking change detection
apx search # Search across all APIs
apx gen <lang> # Code generation for supported formats
Best Practices¶
Directory Naming¶
- Use kebab-case for directory names:
user-service,payment-gateway - Group related APIs under common domains:
payments/,users/,analytics/ - Keep names concise but descriptive
Ownership Boundaries¶
- Assign clear ownership via CODEOWNERS
- One team per API path for accountability
- API governance team as fallback owners
Versioning Strategy¶
- Start with v1, add v2 only when introducing breaking changes
- Keep v1 maintained until consumers migrate
- Use semantic versioning for all releases
Documentation¶
- Include README.md in each API directory
- Document breaking changes in CHANGELOG.md
- Use proto comments for API documentation