Skip to content

feat(service): transparent pass-through proxy for unhandled provider endpoints#106

Merged
carlosatta merged 1 commit into
developfrom
feat/passthrough-proxy-issue-100
Jun 13, 2026
Merged

feat(service): transparent pass-through proxy for unhandled provider endpoints#106
carlosatta merged 1 commit into
developfrom
feat/passthrough-proxy-issue-100

Conversation

@carlosatta

Copy link
Copy Markdown
Contributor

Summary

Closes #100

  • Any path not explicitly handled by Routerly is now forwarded to the project's upstream provider with only the API key swapped — makes Routerly a true drop-in replacement today and for any future provider endpoints without requiring updates
  • Upstream is selected by matching the request body's model field against project models, falling back to the first configured model; Anthropic/anthropic-web use x-api-key, all other providers use Authorization: Bearer
  • Reserved namespaces (/, /health, /api/*, /dashboard*) are guarded inside the handler and always return 404 — never proxied

Changes

  • plugins/auth.ts — extract resolveProjectByToken() as a shared exported helper (no behaviour change to existing auth hook)
  • routes/passthrough.ts — new: pure helpers pickUpstreamModel, buildUpstreamUrl, buildUpstreamHeaders + passthroughHandler registered as fastify.setNotFoundHandler
  • server.ts — add * content-type parser (non-JSON bodies captured as Buffer for verbatim forwarding) + wire setNotFoundHandler
  • server.telemetry.test.ts — add missing mock stubs (addContentTypeParser, passthroughHandler)

Test plan

  • 22 new tests in passthrough.test.ts covering all pure helpers and handler scenarios (model selection, URL building, header injection, proxy flow, auth failures, 502 cases, reserved-path guard)
  • npm test --workspace=packages/service → 1027/1027 passed
  • npm run typecheck --workspace=packages/service → clean

Manual E2E:

# start server
npm run dev

# pass-through: embeddings (not handled by Routerly)
curl -s http://localhost:3000/v1/embeddings \
  -H "Authorization: Bearer <project-token>" \
  -H "content-type: application/json" \
  -d '{"model":"text-embedding-3-small","input":"hello"}'

# reserved path — must return 404, not proxied
curl -i http://localhost:3000/api/does-not-exist \
  -H "Authorization: Bearer <project-token>"

# existing route — must still go through routing engine unchanged
curl -s http://localhost:3000/v1/chat/completions \
  -H "Authorization: Bearer <project-token>" \
  -H "content-type: application/json" \
  -d '{"model":"gpt-4o","messages":[{"role":"user","content":"hi"}]}'

🤖 Generated with Claude Code

…endpoints (#100)

Any path Routerly does not explicitly handle is now forwarded to the
project's upstream provider with only the API key swapped, making
Routerly a true drop-in replacement for OpenAI, Anthropic, Ollama and
custom providers — today and for any future endpoints they add.

- Extract `resolveProjectByToken()` helper from auth plugin (shared by
  the proxy handler so auth is never bypassed)
- Add `passthrough.ts`: pure helpers (`pickUpstreamModel`,
  `buildUpstreamUrl`, `buildUpstreamHeaders`) + `passthroughHandler`
  registered as Fastify's global setNotFoundHandler
- Register a `*` content-type parser in server.ts to capture non-JSON
  bodies as raw Buffer for verbatim forwarding
- Upstream selection: body `model` field matched to project models,
  else first configured model; Anthropic uses x-api-key, all others
  Bearer — no config required
- Reserved namespaces (`/`, `/health`, `/api/*`, `/dashboard*`) are
  guarded inside the handler and never proxied
- 22 new tests covering all helpers and handler scenarios; existing
  server telemetry test updated to include the new mock stubs

Closes #100

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@carlosatta
carlosatta merged commit eb21e43 into develop Jun 13, 2026
2 checks passed
@carlosatta
carlosatta deleted the feat/passthrough-proxy-issue-100 branch June 13, 2026 15:15
@carlosatta carlosatta added the release/0.3.0 Included in release 0.3.0 label Jul 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release/0.3.0 Included in release 0.3.0

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Pass-through endpoints — proxy provider-specific APIs beyond chat completions

1 participant