109 lines
6.5 KiB
PHP
109 lines
6.5 KiB
PHP
@extends('layouts.app')
|
|||
|
|
|
||
|
|
@section('title', 'API Documentation — LoreKeepers')
|
||
|
|
|
||
|
|
@section('content')
|
||
|
|
<div class="max-w-4xl mx-auto px-4 py-10">
|
||
|
|
|
||
|
|
<div class="mb-10">
|
||
|
|
<h1 class="text-3xl font-bold text-white mb-3">API Documentation</h1>
|
||
|
|
<p class="text-slate-400">Programmatic access to the LoreKeepers game database and user libraries.</p>
|
||
|
|
</div>
|
||
|
|
|
||
|
|
<section class="mb-10">
|
||
|
|
<h2 class="text-xl font-semibold text-white mb-4 pb-2 border-b border-white/10">Authentication</h2>
|
||
|
|
<p class="text-slate-400 text-sm mb-3">All API requests require an API key. @auth Generate one in <a href="{{ route('settings.api-keys') }}" class="text-purple-400 hover:text-purple-300 underline">Settings → API Keys</a>. @else <a href="{{ route('register') }}" class="text-purple-400 hover:text-purple-300 underline">Sign up</a> and generate one in Settings → API Keys. @endauth</p>
|
||
|
|
<p class="text-slate-400 text-sm mb-3">Pass the key via the <code class="text-purple-300 bg-white/5 px-1.5 py-0.5 rounded text-xs">Authorization</code> header:</p>
|
||
|
|
<pre class="bg-[#16161d] border border-white/10 rounded-xl p-4 text-sm text-green-300 overflow-x-auto font-mono">Authorization: Bearer YOUR_API_KEY</pre>
|
||
|
|
<p class="text-slate-500 text-sm mt-3">Alternatively, append <code class="text-purple-300 bg-white/5 px-1.5 py-0.5 rounded text-xs">?api_key=YOUR_API_KEY</code> as a query parameter.</p>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="mb-10">
|
||
|
|
<h2 class="text-xl font-semibold text-white mb-4 pb-2 border-b border-white/10">Base URL & Rate Limiting</h2>
|
||
|
|
<div class="grid md:grid-cols-2 gap-4">
|
||
|
|
<div class="bg-[#16161d] border border-white/5 rounded-xl p-4">
|
||
|
|
<div class="text-xs text-slate-500 mb-1 uppercase tracking-wide">Base URL</div>
|
||
|
|
<code class="text-purple-300 font-mono text-sm">https://gamelog.ro/api/v1</code>
|
||
|
|
</div>
|
||
|
|
<div class="bg-[#16161d] border border-white/5 rounded-xl p-4">
|
||
|
|
<div class="text-xs text-slate-500 mb-1 uppercase tracking-wide">Rate Limit</div>
|
||
|
|
<span class="text-white text-sm font-medium">60 requests / minute</span>
|
||
|
|
<p class="text-slate-500 text-xs mt-1">Returns HTTP 429 when exceeded.</p>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="mb-10">
|
||
|
|
<h2 class="text-xl font-semibold text-white mb-4 pb-2 border-b border-white/10">Endpoints</h2>
|
||
|
|
|
||
|
|
@php
|
||
|
|
$endpoints = [
|
||
|
|
['GET', '/games', 'List games', 'Filters: genre (id), platform (id), year, sort (rating|release|title|popular). Paginated 20/page.'],
|
||
|
|
['GET', '/games/search', 'Search games', 'Required: q (min 2 chars). Returns up to 20 matches.'],
|
||
|
|
['GET', '/games/top-rated', 'Top rated games', 'Games with ≥1 rating, sorted by avg rating. Paginated 20/page.'],
|
||
|
|
['GET', '/games/new-releases', 'New releases', 'Games released ≤ today, sorted newest first. Paginated 20/page.'],
|
||
|
|
['GET', '/games/{slug}', 'Game detail', 'Full game info: companies, screenshots, latest 5 reviews.'],
|
||
|
|
['GET', '/genres', 'All genres', 'Returns id, name, slug for all genres.'],
|
||
|
|
['GET', '/platforms', 'All platforms', 'Returns id, name, slug for all platforms.'],
|
||
|
|
['GET', '/users/{slug}', 'User profile', 'Public profile: username, name, avatar, stats, joined date.'],
|
||
|
|
['GET', '/users/{slug}/library', 'User library', "User's game library. Paginated 20/page. Returns game + status + rating."],
|
||
|
|
];
|
||
|
|
@endphp
|
||
|
|
|
||
|
|
<div class="space-y-3">
|
||
|
|
@foreach($endpoints as $ep)
|
||
|
|
<div class="bg-[#16161d] border border-white/5 rounded-xl p-4 flex gap-4 items-start">
|
||
|
|
<span class="flex-shrink-0 text-xs font-mono font-bold px-2 py-1 rounded bg-purple-900/40 text-purple-300 border border-purple-700/30 mt-0.5">{{ $ep[0] }}</span>
|
||
|
|
<div class="min-w-0">
|
||
|
|
<code class="text-green-300 font-mono text-sm">/api/v1{{ $ep[1] }}</code>
|
||
|
|
<div class="text-white text-sm font-medium mt-0.5">{{ $ep[2] }}</div>
|
||
|
|
<div class="text-slate-500 text-xs mt-1">{{ $ep[3] }}</div>
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
@endforeach
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="mb-10">
|
||
|
|
<h2 class="text-xl font-semibold text-white mb-4 pb-2 border-b border-white/10">Response Format</h2>
|
||
|
|
<p class="text-slate-400 text-sm mb-4">All list endpoints return paginated responses wrapped in <code class="text-purple-300 bg-white/5 px-1.5 py-0.5 rounded text-xs">data</code> + <code class="text-purple-300 bg-white/5 px-1.5 py-0.5 rounded text-xs">meta</code>:</p>
|
||
|
|
<pre class="bg-[#16161d] border border-white/10 rounded-xl p-4 text-sm text-green-300 overflow-x-auto font-mono">{
|
||
|
|
"data": [ ... ],
|
||
|
|
"meta": {
|
||
|
|
"current_page": 1,
|
||
|
|
"last_page": 5,
|
||
|
|
"per_page": 20,
|
||
|
|
"total": 93
|
||
|
|
}
|
||
|
|
}</pre>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section class="mb-10">
|
||
|
|
<h2 class="text-xl font-semibold text-white mb-4 pb-2 border-b border-white/10">Example Request</h2>
|
||
|
|
<pre class="bg-[#16161d] border border-white/10 rounded-xl p-4 text-sm text-green-300 overflow-x-auto font-mono">curl https://gamelog.ro/api/v1/games/top-rated \
|
||
|
|
-H "Authorization: Bearer YOUR_API_KEY"</pre>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
<section>
|
||
|
|
<h2 class="text-xl font-semibold text-white mb-4 pb-2 border-b border-white/10">Error Codes</h2>
|
||
|
|
<div class="overflow-x-auto">
|
||
|
|
<table class="w-full text-sm">
|
||
|
|
<thead>
|
||
|
|
<tr class="text-left text-slate-500 text-xs uppercase tracking-wide border-b border-white/10">
|
||
|
|
<th class="pb-2 pr-6">Status</th>
|
||
|
|
<th class="pb-2">Meaning</th>
|
||
|
|
</tr>
|
||
|
|
</thead>
|
||
|
|
<tbody class="text-slate-300">
|
||
|
|
<tr class="border-b border-white/5"><td class="py-2.5 pr-6 font-mono text-yellow-400">401</td><td>Missing or invalid API key</td></tr>
|
||
|
|
<tr class="border-b border-white/5"><td class="py-2.5 pr-6 font-mono text-yellow-400">404</td><td>Resource not found</td></tr>
|
||
|
|
<tr class="border-b border-white/5"><td class="py-2.5 pr-6 font-mono text-yellow-400">422</td><td>Validation error (e.g. q too short)</td></tr>
|
||
|
|
<tr><td class="py-2.5 pr-6 font-mono text-yellow-400">429</td><td>Rate limit exceeded (60 req/min)</td></tr>
|
||
|
|
</tbody>
|
||
|
|
</table>
|
||
|
|
</div>
|
||
|
|
</section>
|
||
|
|
|
||
|
|
</div>
|
||
|
|
@endsection
|