Илья Глазунов 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

173 lines
6.0 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Routing - 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> / Routing
</div>
<div id="content">
<h2>Routing</h2>
<p>pyserve supports nginx-style routing patterns including exact matches,
regex locations, and SPA fallback.</p>
<h3>Location Types</h3>
<table class="dirindex">
<tr>
<td><code>=</code></td>
<td>Exact match</td>
<td class="desc"><code>=/health</code> matches only <code>/health</code></td>
</tr>
<tr>
<td><code>~</code></td>
<td>Case-sensitive regex</td>
<td class="desc"><code>~^/api/v\d+/</code> matches <code>/api/v1/</code></td>
</tr>
<tr>
<td><code>~*</code></td>
<td>Case-insensitive regex</td>
<td class="desc"><code>~*\.(js|css)$</code> matches <code>.JS</code> and <code>.css</code></td>
</tr>
<tr>
<td><code>__default__</code></td>
<td>Default fallback</td>
<td class="desc">Matches when no other route matches</td>
</tr>
</table>
<h3>Match Priority</h3>
<p>Routes are processed in the following order:</p>
<ol class="indent">
<li><strong>Exact matches</strong> (<code>=</code>) — checked first</li>
<li><strong>Regex patterns</strong> (<code>~</code> and <code>~*</code>) — in definition order</li>
<li><strong>Default fallback</strong> (<code>__default__</code>) — last resort</li>
</ol>
<h3>Routing Configuration</h3>
<p>Routing is configured via the <code>routing</code> extension:</p>
<pre><code class="language-yaml">extensions:
- type: routing
config:
regex_locations:
# Exact match for health check
"=/health":
return: "200 OK"
content_type: "text/plain"
# Static files with caching
"~*\\.(js|css|png|jpg|gif|ico)$":
root: "./static"
cache_control: "public, max-age=31536000"
# HTML files without caching
"~*\\.html$":
root: "./static"
cache_control: "no-cache"
# Default fallback
"__default__":
root: "./static"
index_file: "index.html"</code></pre>
<h3>Location Directives</h3>
<dl>
<dt>root</dt>
<dd>Base directory for serving files.</dd>
<dt>index_file</dt>
<dd>Index file name for directory requests. Default: <code>index.html</code></dd>
<dt>proxy_pass</dt>
<dd>Upstream server URL for reverse proxy. See <a href="reverse-proxy.html">Reverse Proxy</a>.</dd>
<dt>return</dt>
<dd>Return a fixed response. Format: <code>"status message"</code> or <code>"status"</code></dd>
<dt>content_type</dt>
<dd>Response content type for <code>return</code> directive.</dd>
<dt>cache_control</dt>
<dd>Cache-Control header value.</dd>
<dt>headers</dt>
<dd>List of additional headers to add. Format: <code>"Header-Name: value"</code></dd>
<dt>spa_fallback</dt>
<dd>Enable SPA mode — serve index file for all routes.</dd>
<dt>exclude_patterns</dt>
<dd>URL patterns to exclude from SPA fallback.</dd>
</dl>
<h3>Named Capture Groups</h3>
<p>Regex locations support named capture groups that can be used in headers and proxy URLs:</p>
<pre><code class="language-bash">"~^/api/v(?P&lt;version&gt;\\d+)/(?P&lt;resource&gt;\\w+)":
proxy_pass: "http://backend:9001"
headers:
- "X-API-Version: {version}"
- "X-Resource: {resource}"</code></pre>
<p>Request to <code>/api/v2/users</code> will have headers:</p>
<ul class="indent">
<li><code>X-API-Version: 2</code></li>
<li><code>X-Resource: users</code></li>
</ul>
<h3>SPA Configuration</h3>
<p>For Single Page Applications, use <code>spa_fallback</code> with <code>exclude_patterns</code>:</p>
<pre><code class="language-python">"__default__":
spa_fallback: true
root: "./dist"
index_file: "index.html"
exclude_patterns:
- "/api/"
- "/assets/"
- "/static/"</code></pre>
<p>This will:</p>
<ul class="indent">
<li>Serve <code>index.html</code> for routes like <code>/about</code>, <code>/users/123</code></li>
<li>Return 404 for <code>/api/*</code>, <code>/assets/*</code>, <code>/static/*</code> if file not found</li>
</ul>
<h3>Static File Serving</h3>
<p>Basic static file configuration:</p>
<pre><code class="language-bash">"~*\\.(css|js|png|jpg|gif|svg|woff2?)$":
root: "./static"
cache_control: "public, max-age=86400"
headers:
- "X-Content-Type-Options: nosniff"</code></pre>
<div class="note">
<strong>Note:</strong> pyserve automatically detects MIME types based on file extensions.
</div>
</div>
<div id="footer">
<p>pyserve &copy; 2024-2025 | MIT License</p>
</div>
</div>
</body>
</html>