This is rabbit-hole, a Go client for the RabbitMQ HTTP API.
It provides a single Client type with methods for managing and monitoring RabbitMQ clusters.
See CONTRIBUTING.md for development setup details.
go build ./...
go vet ./...
go fmt ./...This library uses Ginkgo for tests.
# run all tests (requires a running RabbitMQ node)
go test -vAlways run go build ./... and go vet ./... before making changes to verify the codebase compiles
and passes static analysis. If either fails, investigate and fix errors before proceeding with any modifications.
At the end of each task, run go fmt ./....
Tests are integration tests that require a locally running RabbitMQ node with the management plugin enabled and specific virtual hosts, users, and plugins configured.
The following Make target starts a fully configured node in a container:
gmake docker.rabbitmq
# In a separate shell
go test -vgmake docker.rabbitmq creates the rabbit/hole virtual host, the policymaker user, and enables
the rabbitmq_federation, rabbitmq_federation_management, rabbitmq_shovel, and
rabbitmq_shovel_management plugins.
Alternatively, start a local RabbitMQ node any way you like, then run bin/ci/before_build.sh that will
set it up:
./bin/ci/before_build.sh
go test -vThis script enables the required plugins, reduces the stats emission interval, and creates the
virtual hosts and users the test suite expects. It requires rabbitmqctl to be in PATH, or the
RABBITHOLE_RABBITMQCTL environment variable to point to it.
All library code lives at the top level of the repository (single package, no subdirectories):
client.go:Clienttype, constructor functions (NewClient,NewTLSClient), request helperserror.go:ErrorResponsetype and error handlingcommon.go: shared data types and custom JSON unmarshalersdoc.go: package-level documentation with usage examples- Domain-specific files by resource type:
vhosts.go,vhost_limits.go,vhosts_channels.go,vhosts_connections.gousers.go,permissions.go,topic_permissions.go,user_limits.goexchanges.go,queues.go,bindings.go,consumers.gopolicies.go,operator_policies.gonodes.go,cluster.go,health_checks.gofederation.go,federation_links.go,shovels.go,streams.goruntime_parameters.go,global_parameters.go,feature_flags.godefinitions.go,plugins.go,deprecated_features.go,misc.go
*_test.go: integration and unit tests using Ginkgo v2 and Gomegago.mod: module definition (github.com/michaelklishin/rabbit-hole/v3)Makefile: common development targetsbin/ci/before_build.sh: configures an existing RabbitMQ node for the test suite (plugins, vhosts, users, stats interval)
- Types:
PascalCase—VhostInfo,QueueSettings,ExchangeInfo *Infosuffix for read-only API response structs (e.g.QueueInfo,NodeInfo)*Settingssuffix for mutable request structs used to create or update resources (e.g.QueueSettings,VhostSettings)- Client methods: verb-first
PascalCase—ListQueues,GetExchange,DeclareQueue,DeleteBinding - JSON struct tags:
snake_case(matching RabbitMQ HTTP API conventions)
Each resource domain follows a consistent pattern:
// List/Get — HTTP GET, returns parsed response
func (c *Client) ListQueues() (rec []QueueInfo, err error)
func (c *Client) GetQueue(vhost, queue string) (rec *QueueInfo, err error)
// Create/Update — HTTP PUT with JSON body, returns raw *http.Response
func (c *Client) DeclareQueue(vhost string, queue string, info QueueSettings) (res *http.Response, err error)
// Delete — HTTP DELETE, returns raw *http.Response; 404 is treated as success (idempotent)
func (c *Client) DeleteQueue(vhost, queue string) (res *http.Response, err error)The library handles RabbitMQ API quirks with custom unmarshalers for types that can appear
as multiple JSON types: Port (int, string, or "undefined"), URISet (string or array),
AutoDelete (bool or "undefined"), UserTags (comma-separated string or array).
Follow the same pattern in common.go when adding new fields with ambiguous types.
rabbithole_suite_test.go: Ginkgo suite bootstrap (TestRabbitHole) and shared setuprabbithole_test.go: main integration test suite (requires a running RabbitMQ node)unit_test.go: Ginkgo specs for custom JSON unmarshaling; can be isolated with--ginkgo.focus="Unit tests"health_checks_test.go: health check endpoint testspolicies_test.go: policy and operator policy testsdeprecated_features_test.go: Ginkgo specs forDeprecationPhaseJSON unmarshaling
All specs run under the single TestRabbitHole suite function. Use Ginkgo's --ginkgo.focus flag
to filter by description substring:
# Run all specs
go test -v -run TestRabbitHole
# Run specs whose description contains "ListQueues"
go test -v -run TestRabbitHole --ginkgo.focus="ListQueues"
# Run only unit specs
go test -v -run TestRabbitHole --ginkgo.focus="Unit tests"The Ginkgo CLI can also be used. Install it first (match the version in go.mod):
go install github.com/onsi/ginkgo/v2/ginkgo@v2.28.2
ginkgo --focus="ListQueues" -v- RabbitMQ HTTP API Reference
- RabbitMQ Documentation
- Rust sibling client:
../rabbitmq-http-api-client-rs.git— reference for API coverage and design
Treat the RabbitMQ documentation as the ultimate first party source of truth.
If asked to perform change log updates, consult and modify ChangeLog.md and stick to its
existing writing style (## Changes Between X.Y.Z and A.B.C (date) headings).
Suppose ChangeLog.md has a ## Changes Between 3.N.0 and 3.(N+1).0 (in development) section at the top.
To produce a new release:
- Update the changelog: replace
(in development)with today's date, e.g.(Apr 27, 2026). Make sure all notable changes since the previous release are listed - Commit with the message
3.(N+1).0(just the version number, nothing else) - Tag the commit:
git tag v3.(N+1).0 - Add a new
## Changes Between 3.(N+1).0 and 3.(N+2).0 (in development)section toChangeLog.mdwithNo changes yet.underneath - Commit with the message
Bump dev version - Push:
git push && git push --tags
Go module consumers resolve the version from the git tag. No additional publish step is needed.
For verifying YAML file syntax, use yq, Ruby or Python YAML modules (whichever is available).
- Only add comments that express non-obvious intent — hidden constraints, subtle invariants, or workarounds for specific bugs
- Keep comments concise
- Do not commit changes automatically without explicit permission to do so
- Never add yourself as a git commit coauthor
- Never mention yourself in commit messages in any way (no "Generated by", no AI tool links, etc)
- Never add full stops to Markdown list items
- Use backticks for type names, method names, field names, and file names
- "virtual host" in documentation, even though
vhostis used in code
After completing a task, perform up to twenty iterative reviews of your changes. In every iteration, look for meaningful improvements that were missed, for gaps in test coverage, and for deviations from the instructions in this file.
In particular, check that:
- New client methods follow the established naming and return-type conventions (
*Infofor reads,*http.Responsefor writes) - Custom JSON unmarshaling is added for any field that the RabbitMQ API returns as multiple possible types
- Notable user-visible changes are listed in
ChangeLog.mdunder the current(in development)section - New behavior is covered by integration tests in
rabbithole_test.goor a dedicated*_test.gofile - No new external runtime dependencies were introduced beyond what is already in
go.mod
If no meaningful improvements are found for three iterations in a row, report it and stop iterating.