mirror of
https://github.com/DevVoxel/VectorDNS.git
synced 2026-02-27 05:47:38 +00:00
- /docs route with sidebar navigation and index page - Architecture section: system overview with React Flow diagram, data flow, database schema - API reference, configuration guide, and self-hosting docs for Go DNS server - Feature planning document for future development - Added docs link to landing page nav
413 lines
13 KiB
TypeScript
413 lines
13 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { FileCode, ArrowRight, CheckCircle, XCircle } from "lucide-react";
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from "@/components/ui/card";
|
|
import { Badge } from "@/components/ui/badge";
|
|
import { Separator } from "@/components/ui/separator";
|
|
|
|
export const metadata: Metadata = {
|
|
title: "API Reference",
|
|
};
|
|
|
|
function Method({ method }: { method: string }) {
|
|
const colors: Record<string, string> = {
|
|
GET: "bg-blue-500/10 text-blue-400 border-blue-500/20",
|
|
POST: "bg-green-500/10 text-green-400 border-green-500/20",
|
|
};
|
|
return (
|
|
<span
|
|
className={`inline-flex items-center rounded border px-2 py-0.5 font-mono text-xs font-semibold ${colors[method] ?? "bg-muted text-muted-foreground"}`}
|
|
>
|
|
{method}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
function CodeBlock({ code }: { code: string }) {
|
|
return (
|
|
<pre className="overflow-x-auto rounded-md border bg-muted/50 p-4 font-mono text-sm leading-relaxed">
|
|
<code>{code.trim()}</code>
|
|
</pre>
|
|
);
|
|
}
|
|
|
|
function StatusBadge({ code }: { code: number }) {
|
|
const isOk = code < 400;
|
|
return (
|
|
<span
|
|
className={`inline-flex items-center gap-1 rounded px-1.5 py-0.5 font-mono text-xs font-medium ${isOk ? "bg-green-500/10 text-green-400" : "bg-red-500/10 text-red-400"}`}
|
|
>
|
|
{isOk ? (
|
|
<CheckCircle className="size-3" />
|
|
) : (
|
|
<XCircle className="size-3" />
|
|
)}
|
|
{code}
|
|
</span>
|
|
);
|
|
}
|
|
|
|
export default function ApiReferencePage() {
|
|
return (
|
|
<div className="space-y-10">
|
|
{/* Header */}
|
|
<div>
|
|
<div className="mb-3 flex items-center gap-2 text-sm text-muted-foreground">
|
|
<FileCode className="size-4" />
|
|
<span>Go Server</span>
|
|
<ArrowRight className="size-3" />
|
|
<span>API Reference</span>
|
|
</div>
|
|
<h1 className="text-3xl font-bold tracking-tight">API Reference</h1>
|
|
<p className="mt-2 text-muted-foreground">
|
|
Complete reference for the VectorDNS Go server REST API.
|
|
</p>
|
|
</div>
|
|
|
|
{/* Base URL & Auth */}
|
|
<Card>
|
|
<CardHeader>
|
|
<CardTitle className="text-base">
|
|
Base URL & Authentication
|
|
</CardTitle>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<div>
|
|
<p className="mb-2 text-sm text-muted-foreground">Base URL</p>
|
|
<CodeBlock code="https://<your-vps-host>/api/v1" />
|
|
</div>
|
|
<div>
|
|
<p className="mb-2 text-sm text-muted-foreground">
|
|
All requests (except{" "}
|
|
<span className="font-mono text-xs">/health</span>) require an API
|
|
key header:
|
|
</p>
|
|
<CodeBlock code="X-API-Key: <your-shared-secret>" />
|
|
</div>
|
|
<p className="text-sm text-muted-foreground">
|
|
Set{" "}
|
|
<span className="font-mono text-xs bg-muted px-1 py-0.5 rounded">
|
|
API_KEY
|
|
</span>{" "}
|
|
in your server environment to enable authentication. If left empty,
|
|
auth is disabled (not recommended for production).
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Endpoints */}
|
|
<div className="space-y-6">
|
|
<h2 className="text-xl font-semibold tracking-tight">Endpoints</h2>
|
|
|
|
{/* DNS Lookup */}
|
|
<Card>
|
|
<CardHeader>
|
|
<div className="flex items-center gap-3">
|
|
<Method method="POST" />
|
|
<code className="font-mono text-sm font-semibold">
|
|
/dns/lookup
|
|
</code>
|
|
</div>
|
|
<CardDescription>
|
|
Resolve DNS records for a domain. Query one or more record types
|
|
in a single request.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<div>
|
|
<p className="mb-2 text-sm font-medium">Request</p>
|
|
<CodeBlock
|
|
code={`{
|
|
"domain": "example.com",
|
|
"types": ["A", "AAAA", "MX", "TXT", "NS", "CNAME", "SOA", "CAA", "SRV"],
|
|
"nameserver": "8.8.8.8"
|
|
}`}
|
|
/>
|
|
<ul className="mt-3 space-y-1 text-sm text-muted-foreground">
|
|
<li>
|
|
<span className="font-mono text-xs text-foreground">
|
|
domain
|
|
</span>{" "}
|
|
<Badge variant="secondary" className="text-xs">
|
|
required
|
|
</Badge>{" "}
|
|
— The domain to query.
|
|
</li>
|
|
<li>
|
|
<span className="font-mono text-xs text-foreground">
|
|
types
|
|
</span>{" "}
|
|
<Badge variant="outline" className="text-xs">
|
|
optional
|
|
</Badge>{" "}
|
|
— Record types to query. Defaults to all 9 supported types if
|
|
omitted.
|
|
</li>
|
|
<li>
|
|
<span className="font-mono text-xs text-foreground">
|
|
nameserver
|
|
</span>{" "}
|
|
<Badge variant="outline" className="text-xs">
|
|
optional
|
|
</Badge>{" "}
|
|
— Specific nameserver to query. Defaults to system resolver.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<Separator />
|
|
<div>
|
|
<div className="mb-2 flex items-center gap-2">
|
|
<p className="text-sm font-medium">Response</p>
|
|
<StatusBadge code={200} />
|
|
</div>
|
|
<CodeBlock
|
|
code={`{
|
|
"domain": "example.com",
|
|
"nameserver": "8.8.8.8",
|
|
"records": {
|
|
"A": [{ "value": "93.184.216.34", "ttl": 300 }],
|
|
"MX": [{ "value": "mail.example.com", "priority": 10, "ttl": 3600 }]
|
|
},
|
|
"query_time_ms": 12
|
|
}`}
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* DNS Propagation */}
|
|
<Card>
|
|
<CardHeader>
|
|
<div className="flex items-center gap-3">
|
|
<Method method="POST" />
|
|
<code className="font-mono text-sm font-semibold">
|
|
/dns/propagation
|
|
</code>
|
|
</div>
|
|
<CardDescription>
|
|
Check DNS propagation across multiple public resolvers. Queries
|
|
resolvers in parallel and compares results.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<div>
|
|
<p className="mb-2 text-sm font-medium">Request</p>
|
|
<CodeBlock
|
|
code={`{
|
|
"domain": "example.com",
|
|
"type": "A",
|
|
"resolvers": ["8.8.8.8", "1.1.1.1", "9.9.9.9"]
|
|
}`}
|
|
/>
|
|
<ul className="mt-3 space-y-1 text-sm text-muted-foreground">
|
|
<li>
|
|
<span className="font-mono text-xs text-foreground">
|
|
domain
|
|
</span>{" "}
|
|
<Badge variant="secondary" className="text-xs">
|
|
required
|
|
</Badge>{" "}
|
|
— The domain to check.
|
|
</li>
|
|
<li>
|
|
<span className="font-mono text-xs text-foreground">
|
|
type
|
|
</span>{" "}
|
|
<Badge variant="secondary" className="text-xs">
|
|
required
|
|
</Badge>{" "}
|
|
— The record type to check (e.g.{" "}
|
|
<span className="font-mono text-xs">A</span>,{" "}
|
|
<span className="font-mono text-xs">MX</span>).
|
|
</li>
|
|
<li>
|
|
<span className="font-mono text-xs text-foreground">
|
|
resolvers
|
|
</span>{" "}
|
|
<Badge variant="outline" className="text-xs">
|
|
optional
|
|
</Badge>{" "}
|
|
— List of resolver IPs. Defaults to a built-in list of public
|
|
resolvers.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<Separator />
|
|
<div>
|
|
<div className="mb-2 flex items-center gap-2">
|
|
<p className="text-sm font-medium">Response</p>
|
|
<StatusBadge code={200} />
|
|
</div>
|
|
<CodeBlock
|
|
code={`{
|
|
"domain": "example.com",
|
|
"type": "A",
|
|
"results": [
|
|
{ "resolver": "8.8.8.8", "values": ["93.184.216.34"], "ttl": 300 },
|
|
{ "resolver": "1.1.1.1", "values": ["93.184.216.34"], "ttl": 280 },
|
|
{ "resolver": "9.9.9.9", "values": ["93.184.216.34"], "ttl": 295 }
|
|
],
|
|
"consistent": true
|
|
}`}
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* DNSSEC Validate */}
|
|
<Card>
|
|
<CardHeader>
|
|
<div className="flex items-center gap-3">
|
|
<Method method="POST" />
|
|
<code className="font-mono text-sm font-semibold">
|
|
/dns/validate
|
|
</code>
|
|
</div>
|
|
<CardDescription>
|
|
DNSSEC validation for a domain. Checks the AD flag and verifies
|
|
the signature chain.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<div>
|
|
<p className="mb-2 text-sm font-medium">Request</p>
|
|
<CodeBlock
|
|
code={`{
|
|
"domain": "example.com"
|
|
}`}
|
|
/>
|
|
<ul className="mt-3 space-y-1 text-sm text-muted-foreground">
|
|
<li>
|
|
<span className="font-mono text-xs text-foreground">
|
|
domain
|
|
</span>{" "}
|
|
<Badge variant="secondary" className="text-xs">
|
|
required
|
|
</Badge>{" "}
|
|
— The domain to validate.
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
<Separator />
|
|
<div>
|
|
<div className="mb-2 flex items-center gap-2">
|
|
<p className="text-sm font-medium">Response</p>
|
|
<StatusBadge code={200} />
|
|
</div>
|
|
<CodeBlock
|
|
code={`{
|
|
"domain": "example.com",
|
|
"dnssec": true,
|
|
"chain_valid": true,
|
|
"details": "RRSIG verified for A record"
|
|
}`}
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
{/* Health */}
|
|
<Card>
|
|
<CardHeader>
|
|
<div className="flex items-center gap-3">
|
|
<Method method="GET" />
|
|
<code className="font-mono text-sm font-semibold">/health</code>
|
|
</div>
|
|
<CardDescription>
|
|
Health check endpoint. No authentication required. Use this for
|
|
uptime monitoring.
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent className="space-y-4">
|
|
<div>
|
|
<div className="mb-2 flex items-center gap-2">
|
|
<p className="text-sm font-medium">Response</p>
|
|
<StatusBadge code={200} />
|
|
</div>
|
|
<CodeBlock
|
|
code={`{
|
|
"status": "ok",
|
|
"version": "0.1.0"
|
|
}`}
|
|
/>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
|
|
{/* Errors */}
|
|
<div className="space-y-4">
|
|
<h2 className="text-xl font-semibold tracking-tight">
|
|
Error Responses
|
|
</h2>
|
|
<p className="text-sm text-muted-foreground">
|
|
All errors return a consistent JSON body:
|
|
</p>
|
|
<CodeBlock
|
|
code={`{
|
|
"error": "invalid domain",
|
|
"code": "INVALID_DOMAIN"
|
|
}`}
|
|
/>
|
|
<Card>
|
|
<CardContent className="pt-6">
|
|
<table className="w-full text-sm">
|
|
<thead>
|
|
<tr className="border-b text-left text-muted-foreground">
|
|
<th className="pb-2 pr-4 font-medium">Status</th>
|
|
<th className="pb-2 pr-4 font-medium">Code</th>
|
|
<th className="pb-2 font-medium">Description</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y">
|
|
{[
|
|
{
|
|
status: 400,
|
|
code: "INVALID_DOMAIN",
|
|
desc: "Malformed or missing domain",
|
|
},
|
|
{
|
|
status: 400,
|
|
code: "INVALID_TYPE",
|
|
desc: "Unsupported record type",
|
|
},
|
|
{
|
|
status: 401,
|
|
code: "UNAUTHORIZED",
|
|
desc: "Missing or invalid API key",
|
|
},
|
|
{
|
|
status: 500,
|
|
code: "DNS_ERROR",
|
|
desc: "Upstream DNS query failed",
|
|
},
|
|
{
|
|
status: 500,
|
|
code: "INTERNAL",
|
|
desc: "Unexpected server error",
|
|
},
|
|
].map((row) => (
|
|
<tr key={row.code}>
|
|
<td className="py-2 pr-4">
|
|
<StatusBadge code={row.status} />
|
|
</td>
|
|
<td className="py-2 pr-4">
|
|
<code className="font-mono text-xs">{row.code}</code>
|
|
</td>
|
|
<td className="py-2 text-muted-foreground">{row.desc}</td>
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|