Skip to content

[Feature Request] API versioning (/api/v1/) and REST best practices roadmap #815

@strausmann

Description

@strausmann

Summary

We are building stable integrations on top of Dockhand (MCP servers, Ansible modules, Terraform providers) and are running into a fundamental limitation: the API has no versioning, making it difficult to build consumers that can rely on stable contracts.

This issue complements #814 (OpenAPI/Swagger) and is related to #543 and #729 (API token auth). We believe these three together form the foundation for a first-class developer experience.


1. Problem: No API Versioning

  • All 130+ endpoints live under /api/ without a version prefix
  • Breaking changes affect all consumers immediately
  • There is no deprecation mechanism for removed or changed endpoints
  • Integrators cannot pin to a stable API version
  • This is a blocker for building stable MCP servers, Ansible modules, and Terraform providers

2. Proposed Solution: Versioned API

  • Introduce /api/v1/ prefix for all current endpoints
  • Keep /api/ as an alias for the latest version (backward compatible, no migration needed immediately)
  • Future breaking changes go to /api/v2/
  • Deprecation headers on old versions (Sunset header, RFC 8594)
  • Maintain a changelog for API versions

3. Additional REST Best Practices (suggestions, not demands)

These are common patterns that would significantly improve the developer experience. We offer them as suggestions — the team knows the codebase best.

a) Pagination on list endpoints

GET /api/v1/containers?page=1&per_page=50

Response headers: X-Total-Count, Link (rel=next/prev)

Currently all list endpoints return full result sets — this becomes problematic at scale.

b) Filtering and Sorting

GET /api/v1/containers?status=running&environment_id=7&sort=name

Reduces client-side processing and bandwidth significantly for large environments.

c) Rate-Limit Headers

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1711234567
Retry-After: 30  (on 429 responses)

We experienced rate limiting in practice (during Hawser authentication flows) but it is currently undocumented. Exposing these headers would help integrators handle backoff correctly.

d) Consistent Error Responses

A standard error envelope across all endpoints:

{
  "error": "Human-readable message",
  "code": "MACHINE_READABLE_CODE",
  "details": {}
}

Combined with consistent HTTP status code usage, this greatly simplifies error handling in consumers.

e) ETag / If-None-Match for Caching

Reduces unnecessary data transfer for polling consumers (e.g., monitoring agents that poll container status every N seconds).


4. Suggested Migration Path

Phase Action Breaking?
1 Add /api/v1/ as alias for all current /api/ routes No
2 Generate OpenAPI spec from /api/v1/ routes (see #814) No
3 New features only on /api/v1/ or later No
4 Deprecate unversioned /api/ (long timeline, with Sunset headers) Soft

5. Why This Matters

Re: #813 — We recently struggled to find the correct token endpoint because the API structure is undiscoverable without documentation. The endpoint existed, but we could not find it. Versioning + OpenAPI (#814) together solve this permanently by making the API self-describing.

Re: #543 and #729 — Community members have been requesting API token authentication for a long time. A versioned API is a natural prerequisite for stable token-based access, as token consumers need a stable contract.

Re: enterprise adoption — Versioned APIs are table stakes for production integrations. Organizations that want to build automation pipelines on top of Dockhand need the confidence that an update to Dockhand will not silently break their tooling.


6. We Offer to Help

We have already mapped all 130+ endpoints from the source code as part of our work on #814. Specifically:

  • We can help draft the /api/v1/ aliasing approach if the team approves the direction
  • Our existing endpoint map can bootstrap the OpenAPI spec
  • We are happy to review PRs or provide test cases from our integration suite

We are not asking for a specific timeline — just opening the discussion and signaling that we are willing to contribute if the approach aligns with the project roadmap.


References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions