App Repo Layout#
This page describes the directory structure of an APX app repository β where files live, what each configuration file does, and how generated code and overlays fit into the tree.
Complete Directory Structure#
<app-repo>/
βββ go.mod # your application module
βββ go.sum # Go checksum database
βββ go.work # managed by apx sync β overlays canonical β local
βββ apx.yaml # APX configuration (identity, release, policy)
βββ apx.lock # pinned toolchain and dependency versions
βββ buf.yaml # Buf lint and breaking-change policy
βββ buf.gen.yaml # Buf code generation plugin config
βββ buf.work.yaml # Buf workspace β aggregates version dirs
βββ .gitignore # must exclude internal/gen/ and .apx-tools/
βββ .github/
β βββ workflows/
β βββ apx-release.yml # CI workflow for tag-triggered releasing
βββ internal/
β βββ apis/ # schema source files (committed)
β β βββ proto/
β β βββ payments/
β β βββ ledger/
β β βββ v1/
β β β βββ ledger.proto
β β βββ v2/ # future breaking version line
β β βββ ledger.proto
β βββ gen/ # generated code (git-ignored, never committed)
β β βββ go/
β β β βββ proto/payments/ledger@v1.2.3/
β β β βββ go.mod # module github.com/<org>/apis/proto/payments/ledger
β β β βββ v1/
β β β βββ ledger.pb.go
β β β βββ ledger_grpc.pb.go
β β βββ python/
β β β βββ proto/payments/ledger/
β β β βββ ledger_pb2.py
β β βββ java/
β β βββ proto/payments/ledger/
β β βββ LedgerServiceGrpc.java
β βββ service/ # your application code
β βββ payment_service.go # imports canonical paths
βββ cmd/
β βββ server/
β βββ main.go # imports github.com/<org>/apis/proto/payments/ledger/v1
βββ .apx-tools/ # cached toolchain binaries (git-ignored)
β βββ buf
β βββ protoc-gen-go
βββ Makefile # optional β can wrap apx commands
Top-Level Files#
apx.yaml#
The primary APX configuration file. Created by apx init app and committed to the repo.
version: 1
org: <org>
repo: <app-repo>
# import_root: go.<org>.dev/apis # optional: custom Go import prefix
module_roots:
- internal/apis/proto
api:
id: proto/payments/ledger/v1
format: proto
domain: payments
name: ledger
line: v1
lifecycle: beta # experimental β beta β stable β deprecated β sunset
source:
repo: github.com/<org>/apis
path: proto/payments/ledger/v1
releases:
current: v1.0.0-beta.1
languages:
go:
module: github.com/<org>/apis/proto/payments/ledger
import: github.com/<org>/apis/proto/payments/ledger/v1
language_targets:
go:
enabled: true
plugins:
- name: protoc-gen-go
version: v1.64.0
- name: protoc-gen-go-grpc
version: v1.5.0
release:
tag_format: "{subdir}/v{version}"
ci_only: true
Most fields after api.id, source.repo, and api.lifecycle are derived automatically by apx init app or apx identity. They are shown here for reference. When import_root is set, Go module and import paths use the custom root instead of source.repo.
apx.lock#
Pins exact versions and checksums for every tool and dependency. Created on first apx fetch or apx add, and should be committed.
version: 1
toolchains:
buf:
version: v1.50.0
checksum: sha256:abc123...
protoc-gen-go:
version: v1.64.0
checksum: sha256:def456...
dependencies:
proto/users/profile/v1:
repo: github.com/<org>/apis
ref: proto/users/profile/v1/v1.0.1
modules:
- proto/users/profile
buf.yaml#
Buf linting and breaking-change policy for protobuf schemas:
version: v1
name: buf.build/<org>/<app-repo>
lint:
use:
- DEFAULT
except:
- UNARY_RPC
breaking:
use:
- FILE
buf.gen.yaml#
Buf code generation plugin configuration:
version: v1
plugins:
- plugin: buf.build/protocolbuffers/go
out: gen/go
opt: paths=source_relative
- plugin: buf.build/grpc/go
out: gen/go
opt: paths=source_relative
Note
During apx gen go, APX uses the overlay manager rather than raw buf generate to ensure the generated code has canonical module paths and go.mod files. The buf.gen.yaml configuration is used as input but the output location is managed by APX.
buf.work.yaml#
Buf workspace that aggregates all version directories:
version: v1
directories:
- internal/apis/proto/**/v1
- internal/apis/proto/**/v2
go.work#
Managed by apx sync. Maps canonical module paths to local overlay directories:
go 1.22
use .
use ./internal/gen/go/proto/payments/ledger@v1.2.3
use ./internal/gen/go/proto/users/profile@v1.0.1
Warning
Do not edit go.work manually. Use apx sync to regenerate it. CI environments regenerate it from apx.lock via apx gen go && apx sync.
.gitignore#
Must exclude generated code and cached tools:
# APX generated code β regenerated from apx.lock
internal/gen/
# APX toolchain cache
.apx-tools/
# Go workspace β regenerated by apx sync
go.work
go.work.sum
Source Schemas β internal/apis/#
Schema source files are the only files you author directly. They live under internal/apis/ organized by format, domain, name, and version line:
internal/apis/
βββ proto/
βββ payments/
βββ ledger/
βββ v1/
β βββ ledger.proto # service + messages
β βββ types.proto # shared types
βββ v2/ # separate version line
βββ ledger.proto
Convention:
internal/prevents Go from vendoring schema directoriesFormat directories (
proto/,openapi/,avro/, etc.) match the canonical repo layoutVersion directories (
v1/,v2/) separate breaking API linesSchema files set
go_packageto the canonical import path
Supported Formats#
Format |
Directory |
File Extensions |
|---|---|---|
Protocol Buffers |
|
|
OpenAPI |
|
|
Avro |
|
|
JSON Schema |
|
|
Parquet |
|
|
Generated Code β internal/gen/#
Generated code lives under internal/gen/, organized by language. This entire directory is git-ignored β it is regenerated from apx.lock by running apx gen <lang>.
Go Overlays#
Go overlays include a synthesized go.mod with the canonical module path, enabling go.work resolution:
internal/gen/go/
βββ proto/payments/ledger@v1.2.3/
βββ go.mod # module github.com/<org>/apis/proto/payments/ledger
βββ v1/
βββ ledger.pb.go # package ledgerv1
βββ ledger_grpc.pb.go # gRPC stubs
The @v1.2.3 suffix in the directory name is the pinned version from apx.lock. It ensures that different versions of the same API donβt collide.
Other Languages#
Non-Go languages use their own resolution mechanisms and donβt need go.mod or go.work entries:
internal/gen/python/proto/payments/ledger/
βββ ledger_pb2.py
internal/gen/java/proto/payments/ledger/
βββ LedgerServiceGrpc.java
Toolchain Cache β .apx-tools/#
apx fetch downloads pinned tool versions into .apx-tools/. This directory is git-ignored:
.apx-tools/
βββ buf # Buf CLI
βββ protoc-gen-go # Go protobuf plugin
βββ protoc-gen-go-grpc # Go gRPC plugin
Versions and checksums are recorded in apx.lock, ensuring all team members and CI use identical toolchains.
CI Workflows β .github/workflows/#
apx-release.yml#
Generated by apx workflows sync. Triggered when you push a tag matching the configured tag_format:
.github/workflows/
βββ apx-release.yml # tag-triggered: validates β opens PR to canonical repo
See CI Integration for details on the workflow contents and triggers.
Comparison with Canonical Repo#
Aspect |
App Repo |
Canonical Repo |
|---|---|---|
Schemas |
|
|
go.mod |
App module ( |
Per-API |
go.work |
Yes β maps overlays to canonical paths |
Not used |
Generated code |
|
Not present β consumers generate from released schemas |
Config |
|
|
CI |
|
|
Buf config |
|
|
Bootstrapping#
To create this layout from scratch:
cd /path/to/your-app-repo
# Initialize β creates apx.yaml, buf configs, schema dirs, .gitignore entries
apx init app --org=<org> --repo=<app-repo> internal/apis/proto/payments/ledger
# Download pinned toolchain
apx fetch
# Generate code and sync overlays
apx gen go && apx sync
See Quickstart for a complete walkthrough.
Next Steps#
Local Development β day-to-day workflow with these files
Release Workflow β how schemas move from app repo to canonical repo
CI Integration β automated validation and releasing