Skip to content

Add API v2 with structured responses (chi-based rebuild)#42

Merged
renecannao merged 1 commit intomasterfrom
issue33-api-v2-rebuild
Mar 24, 2026
Merged

Add API v2 with structured responses (chi-based rebuild)#42
renecannao merged 1 commit intomasterfrom
issue33-api-v2-rebuild

Conversation

@renecannao
Copy link
Copy Markdown

Summary

  • Adds a new /api/v2 REST API with consistent JSON response envelope (V2APIResponse), proper HTTP status codes, and RESTful URL structure
  • Implements 9 endpoints: clusters, cluster info, cluster instances, topology, instance details, recoveries, active recoveries, status, and ProxySQL servers
  • All handlers use existing inst.*, logic.*, and process.* functions -- no new business logic, just a cleaner API surface
  • Includes unit tests for response helpers and endpoint documentation in docs/api-v2.md

This is a clean rebuild of the original PR #40 on top of the current chi-based router (post-martini migration).

Closes #33

Test plan

  • go build succeeds
  • Unit tests pass (go test ./go/http/... -run TestV2\|TestRespondOK\|TestRespondError\|TestRespondNotFound)
  • Manual smoke test: start orchestrator, verify /api/v2/clusters and /api/v2/status return structured JSON
  • Verify v1 API endpoints still work unchanged

Implement a new v2 REST API mounted at /api/v2 that provides:
- Consistent JSON response envelope (V2APIResponse with status/data/error)
- Proper HTTP status codes (404, 400, 500, 503) instead of always 200
- RESTful URL structure with nested resources
- Machine-readable error codes alongside human-readable messages

Endpoints: clusters, cluster info, cluster instances, topology,
instance details, recoveries, active recoveries, status, and
ProxySQL servers.

Closes #33
Copilot AI review requested due to automatic review settings March 24, 2026 01:07
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 24, 2026

Warning

Rate limit exceeded

@renecannao has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 13 minutes and 3 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 29dfb4ff-abe4-4535-80e0-64b5cb9f5f22

📥 Commits

Reviewing files that changed from the base of the PR and between e08f4b6 and 6030cda.

📒 Files selected for processing (4)
  • docs/api-v2.md
  • go/app/http.go
  • go/http/apiv2.go
  • go/http/apiv2_test.go
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue33-api-v2-rebuild

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly enhances Orchestrator's API by introducing a new version 2. This new API focuses on improving consistency, predictability, and usability through structured JSON responses, appropriate HTTP status codes, and a more RESTful URL design. It provides a modern interface for interacting with Orchestrator's core functionalities without altering the underlying business logic, making it easier for clients to integrate and consume data.

Highlights

  • New API Version: Introduced a new /api/v2 REST API, providing a cleaner and more consistent interface.
  • Structured Responses and HTTP Status Codes: Implemented structured JSON response envelopes and proper HTTP status codes for all v2 endpoints, improving API predictability and error handling.
  • Expanded Endpoints: Added 9 new RESTful endpoints covering clusters, instances, recoveries, status, and ProxySQL servers.
  • Comprehensive Documentation: Included comprehensive documentation for the API v2 in docs/api-v2.md, detailing its structure, endpoints, and response formats.
  • Leveraged Existing Logic: Leveraged existing business logic functions, ensuring no new core functionality was introduced, focusing solely on API surface improvement.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@renecannao renecannao merged commit 0b1c463 into master Mar 24, 2026
3 of 7 checks passed
Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new /api/v2 with a more structured and consistent JSON response format, which is a great improvement over the v1 API. The code is well-organized, with clear separation of concerns using response helpers and chi router for routing. The new endpoints are logical wrappers around existing functionality, minimizing the introduction of new business logic. The inclusion of unit tests for the response helpers and comprehensive documentation for the new API is also commendable.

I have a couple of suggestions to improve the clarity of the new API response structure by removing an unused field from the response envelope and updating the documentation accordingly.

Comment thread docs/api-v2.md

The v2 API wraps the same underlying functions as v1 but provides:

1. **Consistent response envelope**: All responses use the `V2APIResponse` struct with `status`, `data`, `error`, and `message` fields.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The documentation states that the response envelope includes a top-level message field. However, this field is unused in the API responses, and the error message is contained within the error object. This description is misleading and should be corrected to reflect the actual response structure.

Suggested change
1. **Consistent response envelope**: All responses use the `V2APIResponse` struct with `status`, `data`, `error`, and `message` fields.
1. **Consistent response envelope**: All responses use the `V2APIResponse` struct with `status`, `data`, and `error` fields.

Comment thread go/http/apiv2.go
Comment on lines +34 to +39
type V2APIResponse struct {
Status string `json:"status"`
Data interface{} `json:"data,omitempty"`
Error *V2APIError `json:"error,omitempty"`
Message string `json:"message,omitempty"`
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The Message field in V2APIResponse is declared but never used in any of the response helper functions (respondOK, respondError, respondNotFound). This can be confusing for developers maintaining this code and for API consumers, as the error message is already part of the V2APIError struct. To improve clarity and remove dead code, this field should be removed.

Note that this change will require updating the TestV2APIResponseJSONOmitempty test in go/http/apiv2_test.go.

type V2APIResponse struct {
	Status  string      `json:"status"`
	Data    interface{} `json:"data,omitempty"`
	Error   *V2APIError `json:"error,omitempty"`
}

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces a new chi-mounted /api/v2 surface with a consistent JSON envelope (V2APIResponse) and several read-only endpoints, intended to modernize the API without adding new business logic.

Changes:

  • Added /api/v2 router registration and handler implementations with structured success/error envelopes.
  • Added unit tests for v2 response helpers/envelope marshaling behavior.
  • Added API v2 endpoint documentation in docs/api-v2.md.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.

File Description
go/http/apiv2.go Adds v2 response types, helpers, route registration, and 9 v2 handlers
go/http/apiv2_test.go Adds unit tests for v2 response helpers and JSON omitempty behavior
go/app/http.go Mounts v2 routes during HTTP server setup
docs/api-v2.md Documents v2 endpoints and response format

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread go/http/apiv2.go
Comment on lines +190 to +192
if p, err := strconv.Atoi(pageStr); err == nil {
page = p
}
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

page query parsing allows negative values (and ignores parse errors by silently defaulting). logic.ReadRecentRecoveries computes offset as page*config.AuditPageSize, so a negative page yields a negative SQL offset and can break the query. Clamp page to >= 0 (matching v1) and consider returning a 400 for non-integer/negative values instead of silently accepting them.

Suggested change
if p, err := strconv.Atoi(pageStr); err == nil {
page = p
}
p, err := strconv.Atoi(pageStr)
if err != nil || p < 0 {
respondError(w, http.StatusBadRequest, "INVALID_PAGE", "Invalid 'page' parameter; must be a non-negative integer")
return
}
page = p

Copilot uses AI. Check for mistakes.
Comment thread go/http/apiv2.go
Comment on lines +71 to +93
// RegisterV2Routes mounts all v2 API routes under /api/v2 on the given router.
func RegisterV2Routes(r chi.Router) {
prefix := config.Config.URLPrefix
r.Route(fmt.Sprintf("%s/api/v2", prefix), func(r chi.Router) {
// Cluster endpoints
r.Get("/clusters", V2Clusters)
r.Get("/clusters/{name}", V2ClusterInfo)
r.Get("/clusters/{name}/instances", V2ClusterInstances)
r.Get("/clusters/{name}/topology", V2Topology)

// Instance endpoints
r.Get("/instances/{host}/{port}", V2Instance)

// Recovery endpoints
r.Get("/recoveries", V2Recoveries)
r.Get("/recoveries/active", V2ActiveRecoveries)

// Status endpoints
r.Get("/status", V2Status)

// ProxySQL endpoints
r.Get("/proxysql/servers", V2ProxySQLServers)
})
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

API v1 routes are registered with raftReverseProxyMiddleware when raft is enabled (see HttpAPI.registerSingleAPIRequest), ensuring followers proxy requests to the leader. The v2 routes are mounted without this middleware, so in raft mode requests hitting a follower won’t be proxied and may behave inconsistently vs v1. Consider wrapping the entire /api/v2 route group with r.With(raftReverseProxyMiddleware) (the middleware is a no-op when raft is disabled).

Copilot uses AI. Check for mistakes.
Comment thread go/http/apiv2.go
Comment on lines +1 to +15
/*
Copyright 2024 Orchestrator Authors

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
Copy link

Copilot AI Mar 24, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

File header copyright differs from the standard used across existing go/http/* sources (most use Copyright 2014 Outbrain Inc.). If this repo expects consistent license headers, please align this new file’s header with the existing convention to avoid future legal/attribution inconsistencies.

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 3.4: API modernization (versioned REST API)

2 participants