Skip to content

chore: move body parser to axum extract#33

Merged
bzp2010 merged 1 commit intomainfrom
bzp/chore-remove-parse-body
Apr 10, 2026
Merged

chore: move body parser to axum extract#33
bzp2010 merged 1 commit intomainfrom
bzp/chore-remove-parse-body

Conversation

@bzp2010
Copy link
Copy Markdown
Collaborator

@bzp2010 bzp2010 commented Apr 10, 2026

Summary by CodeRabbit

  • New Features

    • Request body size limit of 10 MiB now enforced; oversized requests receive HTTP 413.
  • Bug Fixes

    • Request validation errors now return HTTP 422 instead of HTTP 400.

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

📝 Walkthrough

Walkthrough

Request body extraction refactored from a custom middleware pattern to Axum's built-in Json extractor across chat completions and embeddings handlers. Global body size limit applied at router level; custom body-parsing middleware removed entirely.

Changes

Cohort / File(s) Summary
Handler Request Extraction
src/proxy/handlers/chat_completions/mod.rs, src/proxy/handlers/embeddings/mod.rs
Refactored parameter extraction from Extension<RequestData> to Json<RequestData> extractors; now construct empty Request internally (marked with TODO) instead of receiving one as parameter.
Middleware Refactoring
src/proxy/middlewares/mod.rs
Removed re-export of parse_body module; defined new local RequestModel tuple struct wrapping String with Clone derive.
Body Parsing Middleware Removal
src/proxy/middlewares/parse_body.rs
Deleted 82-line middleware file that previously handled raw body reading, JSON deserialization, and extension insertion.
Router Configuration
src/proxy/mod.rs
Added global DefaultBodyLimit::max(10 * 1024 * 1024) to router; removed per-endpoint parse_body middleware wrapping from /v1/chat/completions and /v1/embeddings routes.
Test Updates
tests/proxy/chat-completions.test.ts, tests/proxy/chat-completions-sim.test.ts, tests/proxy/embeddings.test.ts
Updated error assertions: changed expected HTTP status from 400 to 422 for invalid JSON/missing fields (now extractor errors rather than parse errors); assertions changed from structured error.code checks to plain string validation; added new test for 10 MiB body size rejection with HTTP 413.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
E2e Test Quality Review ⚠️ Warning 10MiB body size limit tested for chat/completions but not embeddings; weak 422 error assertions; missing boundary cases; embeddings handler lacks trace decorator. Add body size limit test to embeddings.test.ts; strengthen 422 assertions to validate error messages; add 10MiB boundary tests; add trace decorator to embeddings handler.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: moving request body parsing from a custom middleware to Axum's built-in JSON extractor.
Security Check ✅ Passed Request body refactoring from custom middleware to Axum Json extractor improves security with proper error handling, body limits preventing DoS, and no sensitive data exposure in responses.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch bzp/chore-remove-parse-body

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

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/proxy/handlers/chat_completions/mod.rs (1)

35-41: Clean migration to Json extractor.

The Json<ChatCompletionRequest> extractor provides built-in deserialization with appropriate error responses (HTTP 422 for validation failures).

The Request::new(Body::empty()) workaround is acceptable given that all current hook implementations ignore the _req parameter (confirmed in validate_model.rs, metric.rs, rate_limit/mod.rs). The TODO appropriately flags this for future cleanup.

When addressing the TODO, consider refactoring the ProxyHook::pre_call trait method to make the Request parameter optional or remove it entirely if no hooks actually need it. This would eliminate the need for dummy request construction.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/proxy/handlers/chat_completions/mod.rs` around lines 35 - 41, The handler
now uses the Json<ChatCompletionRequest> extractor but still constructs a dummy
HTTP Request via Request::new(Body::empty()) before calling
HOOK_MANAGER.pre_call; keep the Json extractor, remove the TODO by either (A)
keeping the temporary Request but add a clear comment referencing that all
current hooks (validate_model.rs, metric.rs, rate_limit/mod.rs) ignore the
request and why the dummy is safe, or (B) refactor the hook trait
ProxyHook::pre_call to accept an Option<Request<Body>> (or remove the Request
parameter) and update HOOK_MANAGER.pre_call and its implementations
(validate_model, metric, rate_limit) to accept None so the dummy Request
creation can be eliminated—update hook_ctx usage and signatures accordingly to
ensure compile-time consistency.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/proxy/handlers/embeddings/mod.rs`:
- Around line 25-36: The embeddings handler is missing the #[fastrace::trace]
decorator required for public handlers; add the #[fastrace::trace] attribute
immediately above the pub async fn embeddings signature to match the
chat_completions handler's tracing setup so this function is instrumented for
distributed tracing (ensure the attribute is imported/available in the module if
needed).

---

Nitpick comments:
In `@src/proxy/handlers/chat_completions/mod.rs`:
- Around line 35-41: The handler now uses the Json<ChatCompletionRequest>
extractor but still constructs a dummy HTTP Request via
Request::new(Body::empty()) before calling HOOK_MANAGER.pre_call; keep the Json
extractor, remove the TODO by either (A) keeping the temporary Request but add a
clear comment referencing that all current hooks (validate_model.rs, metric.rs,
rate_limit/mod.rs) ignore the request and why the dummy is safe, or (B) refactor
the hook trait ProxyHook::pre_call to accept an Option<Request<Body>> (or remove
the Request parameter) and update HOOK_MANAGER.pre_call and its implementations
(validate_model, metric, rate_limit) to accept None so the dummy Request
creation can be eliminated—update hook_ctx usage and signatures accordingly to
ensure compile-time consistency.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2374f894-9db4-409b-8576-7e3c77ec6dab

📥 Commits

Reviewing files that changed from the base of the PR and between 33c6061 and 82b5c1c.

📒 Files selected for processing (8)
  • src/proxy/handlers/chat_completions/mod.rs
  • src/proxy/handlers/embeddings/mod.rs
  • src/proxy/middlewares/mod.rs
  • src/proxy/middlewares/parse_body.rs
  • src/proxy/mod.rs
  • tests/proxy/chat-completions-sim.test.ts
  • tests/proxy/chat-completions.test.ts
  • tests/proxy/embeddings.test.ts
💤 Files with no reviewable changes (1)
  • src/proxy/middlewares/parse_body.rs

Comment on lines 25 to 36
pub async fn embeddings(
State(_state): State<AppState>,
Extension(mut request_data): Extension<EmbeddingRequest>,
mut hook_ctx: HookContext,
mut request: Request,
Json(mut request_data): Json<EmbeddingRequest>,
) -> Result<Response, EmbeddingError> {
// PRE CALL HOOKS START
hook_ctx.insert(RequestModel(request_data.model));

let mut request = Request::new(Body::empty()); //TODO
HOOK_MANAGER
.pre_call(&mut hook_ctx, &mut request, HOOK_FILTER_ALL)
.await?;
Copy link
Copy Markdown

@coderabbitai coderabbitai bot Apr 10, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consistent refactor with chat_completions handler, but missing #[fastrace::trace] decorator.

The Json<EmbeddingRequest> extractor and empty request pattern match the chat_completions handler, which is good for consistency.

However, the embeddings function is missing the #[fastrace::trace] decorator that's present on chat_completions (line 30 in that file). As per coding guidelines, public functions in src/**/*.rs should use this decorator for distributed tracing.

🔧 Proposed fix to add tracing decorator
+#[fastrace::trace]
 pub async fn embeddings(
     State(_state): State<AppState>,
     mut hook_ctx: HookContext,
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
pub async fn embeddings(
State(_state): State<AppState>,
Extension(mut request_data): Extension<EmbeddingRequest>,
mut hook_ctx: HookContext,
mut request: Request,
Json(mut request_data): Json<EmbeddingRequest>,
) -> Result<Response, EmbeddingError> {
// PRE CALL HOOKS START
hook_ctx.insert(RequestModel(request_data.model));
let mut request = Request::new(Body::empty()); //TODO
HOOK_MANAGER
.pre_call(&mut hook_ctx, &mut request, HOOK_FILTER_ALL)
.await?;
#[fastrace::trace]
pub async fn embeddings(
State(_state): State<AppState>,
mut hook_ctx: HookContext,
Json(mut request_data): Json<EmbeddingRequest>,
) -> Result<Response, EmbeddingError> {
// PRE CALL HOOKS START
hook_ctx.insert(RequestModel(request_data.model));
let mut request = Request::new(Body::empty()); //TODO
HOOK_MANAGER
.pre_call(&mut hook_ctx, &mut request, HOOK_FILTER_ALL)
.await?;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/proxy/handlers/embeddings/mod.rs` around lines 25 - 36, The embeddings
handler is missing the #[fastrace::trace] decorator required for public
handlers; add the #[fastrace::trace] attribute immediately above the pub async
fn embeddings signature to match the chat_completions handler's tracing setup so
this function is instrumented for distributed tracing (ensure the attribute is
imported/available in the module if needed).

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

just ignore it for now

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@bzp2010, understood — I'll skip this for now.


🧠 Learnings used
Learnt from: CR
Repo: api7/aisix PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-08T12:40:09.587Z
Learning: Applies to src/**/*.rs : Use #[fastrace::trace] decorator for distributed tracing on public functions

@bzp2010 bzp2010 merged commit 320ea45 into main Apr 10, 2026
10 checks passed
@bzp2010 bzp2010 deleted the bzp/chore-remove-parse-body branch April 10, 2026 08:07
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.

1 participant