docs.pyserve.org/guides/reverse-proxy.html
Илья Глазунов 00119ce463
All checks were successful
Deploy to Production / deploy (push) Successful in 5s
Refactor documentation for reverse proxy and routing guides
2025-12-08 01:05:52 +03:00

160 lines
5.1 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Reverse Proxy - pyserve</title>
<link rel="stylesheet" href="../style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github-dark.min.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
<script>hljs.highlightAll();</script>
</head>
<body>
<div id="container">
<div id="header">
<h1>pyserve</h1>
<div class="tagline">python application orchestrator</div>
</div>
<div class="breadcrumb">
<a href="../index.html">Home</a> / <a href="index.html">Guides</a> / Reverse Proxy
</div>
<div id="content">
<h2>Reverse Proxy</h2>
<p>pyserve can act as a reverse proxy, forwarding requests to backend services.</p>
<h3>Basic Proxy Configuration</h3>
<p>Use the <code>proxy_pass</code> directive in routing:</p>
<pre><code class="language-yaml">extensions:
- type: routing
config:
regex_locations:
"~^/api/":
proxy_pass: "http://localhost:9001"</code></pre>
<p>All requests to <code>/api/*</code> will be forwarded to <code>http://localhost:9001/api/*</code>.</p>
<h3>Proxy Headers</h3>
<p>pyserve automatically adds standard proxy headers:</p>
<table class="dirindex">
<tr>
<td><code>X-Forwarded-For</code></td>
<td>Client's IP address</td>
</tr>
<tr>
<td><code>X-Forwarded-Proto</code></td>
<td>Original protocol (http/https)</td>
</tr>
<tr>
<td><code>X-Forwarded-Host</code></td>
<td>Original Host header</td>
</tr>
<tr>
<td><code>X-Real-IP</code></td>
<td>Client's real IP address</td>
</tr>
</table>
<h3>Custom Headers</h3>
<p>Add custom headers to proxied requests:</p>
<pre><code class="language-bash">"~^/api/":
proxy_pass: "http://localhost:9001"
headers:
- "X-Custom-Header: my-value"
- "Authorization: Bearer token123"</code></pre>
<h3>Dynamic Headers with Captures</h3>
<p>Use regex capture groups to build dynamic headers:</p>
<pre><code class="language-bash">"~^/api/v(?P&lt;version&gt;\\d+)/(?P&lt;service&gt;\\w+)":
proxy_pass: "http://localhost:9001"
headers:
- "X-API-Version: {version}"
- "X-Service: {service}"
- "X-Client-IP: $remote_addr"</code></pre>
<p>Special variables:</p>
<ul class="indent">
<li><code>{capture_name}</code> — Named capture group from regex</li>
<li><code>$remote_addr</code> — Client's IP address</li>
</ul>
<h3>Proxy Timeout</h3>
<p>Configure timeout for proxy requests:</p>
<pre><code class="language-yaml"># Global default timeout
server:
proxy_timeout: 30.0
# Per-route timeout
extensions:
- type: routing
config:
regex_locations:
"~^/api/slow":
proxy_pass: "http://localhost:9001"
timeout: 120 # 2 minutes for slow endpoints</code></pre>
<h3>URL Rewriting</h3>
<p>The proxy preserves the original request path by default:</p>
<pre><code class="language-bash"># Request: GET /api/users/123
# Proxied: GET http://backend:9001/api/users/123
"~^/api/":
proxy_pass: "http://backend:9001"</code></pre>
<p>To proxy to a specific path:</p>
<pre><code class="language-bash"># Request: GET /api/users/123
# Proxied: GET http://backend:9001/v2/users/123 (path preserved)
"~^/api/":
proxy_pass: "http://backend:9001/v2"</code></pre>
<h3>Load Balancing Example</h3>
<p>Route different services to different backends:</p>
<pre><code class="language-yaml">extensions:
- type: routing
config:
regex_locations:
"~^/api/users":
proxy_pass: "http://user-service:8001"
"~^/api/orders":
proxy_pass: "http://order-service:8002"
"~^/api/products":
proxy_pass: "http://product-service:8003"</code></pre>
<h3>Error Handling</h3>
<p>pyserve returns appropriate error codes for proxy failures:</p>
<table class="dirindex">
<tr>
<td><code>502 Bad Gateway</code></td>
<td>Backend connection failed or returned invalid response</td>
</tr>
<tr>
<td><code>504 Gateway Timeout</code></td>
<td>Backend did not respond within timeout</td>
</tr>
</table>
<div class="note">
<strong>Note:</strong> pyserve uses <code>httpx</code> for async HTTP requests
to backend services, supporting HTTP/1.1 and HTTP/2.
</div>
</div>
<div id="footer">
<p>pyserve &copy; 2024-2025 | MIT License</p>
</div>
</div>
</body>
</html>