- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
839 lines
21 KiB
Markdown
839 lines
21 KiB
Markdown
# API-Dokumentation
|
|
|
|
Diese Dokumentation bietet einen Überblick über die API des Frameworks und wie Sie sie verwenden können, um RESTful APIs zu erstellen.
|
|
|
|
## Einführung
|
|
|
|
Das Framework bietet umfassende Unterstützung für die Erstellung von RESTful APIs mit Funktionen wie:
|
|
|
|
- Einfache Routendefinition für API-Endpunkte
|
|
- Automatische Konvertierung von Daten in JSON
|
|
- Validierung von Anfragen
|
|
- Authentifizierung und Autorisierung
|
|
- Versionierung
|
|
- Rate Limiting
|
|
- API-Dokumentation
|
|
|
|
## API-Routen definieren
|
|
|
|
### Grundlegende API-Routen
|
|
|
|
Sie können API-Routen in der Datei `config/routes.php` definieren:
|
|
|
|
```php
|
|
use App\Framework\Routing\Router;
|
|
use App\Application\Controllers\Api\UserController;
|
|
|
|
return function (Router $router) {
|
|
$router->group('/api', function (Router $router) {
|
|
$router->get('/users', [UserController::class, 'index']);
|
|
$router->get('/users/{id}', [UserController::class, 'show']);
|
|
$router->post('/users', [UserController::class, 'store']);
|
|
$router->put('/users/{id}', [UserController::class, 'update']);
|
|
$router->delete('/users/{id}', [UserController::class, 'destroy']);
|
|
});
|
|
};
|
|
```
|
|
|
|
### API-Ressourcen-Routen
|
|
|
|
Für RESTful APIs können Sie API-Ressourcen-Routen verwenden:
|
|
|
|
```php
|
|
$router->apiResource('users', UserController::class);
|
|
```
|
|
|
|
Dies erstellt die folgenden Routen:
|
|
|
|
| HTTP-Methode | URI | Aktion | Routenname |
|
|
|--------------|------------------|----------|----------------|
|
|
| GET | /users | index | users.index |
|
|
| POST | /users | store | users.store |
|
|
| GET | /users/{user} | show | users.show |
|
|
| PUT/PATCH | /users/{user} | update | users.update |
|
|
| DELETE | /users/{user} | destroy | users.destroy |
|
|
|
|
### Verschachtelte API-Ressourcen
|
|
|
|
Sie können auch verschachtelte API-Ressourcen definieren:
|
|
|
|
```php
|
|
$router->apiResource('users.posts', UserPostController::class);
|
|
```
|
|
|
|
Dies erstellt Routen wie:
|
|
- `/users/{user}/posts`
|
|
- `/users/{user}/posts/{post}`
|
|
|
|
### API-Versionierung
|
|
|
|
Sie können verschiedene Versionen Ihrer API unterstützen:
|
|
|
|
```php
|
|
$router->group('/api/v1', function (Router $router) {
|
|
$router->apiResource('users', Api\V1\UserController::class);
|
|
});
|
|
|
|
$router->group('/api/v2', function (Router $router) {
|
|
$router->apiResource('users', Api\V2\UserController::class);
|
|
});
|
|
```
|
|
|
|
## API-Controller
|
|
|
|
API-Controller sind spezielle Controller, die JSON-Antworten zurückgeben:
|
|
|
|
```php
|
|
namespace App\Application\Controllers\Api;
|
|
|
|
use App\Framework\Http\Controller;
|
|
use App\Framework\Http\Request;
|
|
use App\Framework\Http\Response;
|
|
use App\Application\Models\User;
|
|
|
|
class UserController extends Controller
|
|
{
|
|
public function index(Request $request): Response
|
|
{
|
|
$users = User::all();
|
|
|
|
return $this->json([
|
|
'data' => $users
|
|
]);
|
|
}
|
|
|
|
public function show(Request $request, int $id): Response
|
|
{
|
|
$user = User::find($id);
|
|
|
|
if (!$user) {
|
|
return $this->json([
|
|
'error' => 'Benutzer nicht gefunden'
|
|
], 404);
|
|
}
|
|
|
|
return $this->json([
|
|
'data' => $user
|
|
]);
|
|
}
|
|
|
|
public function store(Request $request): Response
|
|
{
|
|
$this->validate($request, [
|
|
'name' => 'required|string|max:255',
|
|
'email' => 'required|email|unique:users,email',
|
|
'password' => 'required|string|min:8',
|
|
]);
|
|
|
|
$user = User::create($request->only(['name', 'email', 'password']));
|
|
|
|
return $this->json([
|
|
'data' => $user,
|
|
'message' => 'Benutzer erstellt'
|
|
], 201);
|
|
}
|
|
|
|
public function update(Request $request, int $id): Response
|
|
{
|
|
$user = User::find($id);
|
|
|
|
if (!$user) {
|
|
return $this->json([
|
|
'error' => 'Benutzer nicht gefunden'
|
|
], 404);
|
|
}
|
|
|
|
$this->validate($request, [
|
|
'name' => 'string|max:255',
|
|
'email' => 'email|unique:users,email,' . $id,
|
|
]);
|
|
|
|
$user->fill($request->only(['name', 'email']));
|
|
$user->save();
|
|
|
|
return $this->json([
|
|
'data' => $user,
|
|
'message' => 'Benutzer aktualisiert'
|
|
]);
|
|
}
|
|
|
|
public function destroy(Request $request, int $id): Response
|
|
{
|
|
$user = User::find($id);
|
|
|
|
if (!$user) {
|
|
return $this->json([
|
|
'error' => 'Benutzer nicht gefunden'
|
|
], 404);
|
|
}
|
|
|
|
$user->delete();
|
|
|
|
return $this->json([
|
|
'message' => 'Benutzer gelöscht'
|
|
]);
|
|
}
|
|
}
|
|
```
|
|
|
|
## API-Antworten
|
|
|
|
### Erfolgsantworten
|
|
|
|
Für Erfolgsantworten können Sie die `json`-Methode verwenden:
|
|
|
|
```php
|
|
// 200 OK
|
|
return $this->json([
|
|
'data' => $users
|
|
]);
|
|
|
|
// 201 Created
|
|
return $this->json([
|
|
'data' => $user,
|
|
'message' => 'Benutzer erstellt'
|
|
], 201);
|
|
|
|
// 204 No Content
|
|
return $this->noContent();
|
|
```
|
|
|
|
### Fehlerantworten
|
|
|
|
Für Fehlerantworten können Sie ebenfalls die `json`-Methode verwenden:
|
|
|
|
```php
|
|
// 400 Bad Request
|
|
return $this->json([
|
|
'error' => 'Ungültige Anfrage'
|
|
], 400);
|
|
|
|
// 401 Unauthorized
|
|
return $this->json([
|
|
'error' => 'Nicht autorisiert'
|
|
], 401);
|
|
|
|
// 403 Forbidden
|
|
return $this->json([
|
|
'error' => 'Zugriff verweigert'
|
|
], 403);
|
|
|
|
// 404 Not Found
|
|
return $this->json([
|
|
'error' => 'Benutzer nicht gefunden'
|
|
], 404);
|
|
|
|
// 422 Unprocessable Entity (Validierungsfehler)
|
|
return $this->json([
|
|
'error' => 'Validierungsfehler',
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
|
|
// 500 Internal Server Error
|
|
return $this->json([
|
|
'error' => 'Serverfehler'
|
|
], 500);
|
|
```
|
|
|
|
### Konsistente Antwortstruktur
|
|
|
|
Es ist wichtig, eine konsistente Antwortstruktur für Ihre API zu haben:
|
|
|
|
```php
|
|
// Erfolgsantwort
|
|
return $this->json([
|
|
'success' => true,
|
|
'data' => $data,
|
|
'message' => $message,
|
|
'meta' => [
|
|
'pagination' => [
|
|
'total' => $total,
|
|
'per_page' => $perPage,
|
|
'current_page' => $currentPage,
|
|
'last_page' => $lastPage,
|
|
]
|
|
]
|
|
]);
|
|
|
|
// Fehlerantwort
|
|
return $this->json([
|
|
'success' => false,
|
|
'error' => $errorMessage,
|
|
'errors' => $validationErrors,
|
|
'code' => $errorCode
|
|
], $statusCode);
|
|
```
|
|
|
|
## API-Ressourcen
|
|
|
|
API-Ressourcen ermöglichen es Ihnen, Modelle in JSON-Antworten zu transformieren:
|
|
|
|
```php
|
|
namespace App\Application\Resources;
|
|
|
|
use App\Framework\Http\Resources\JsonResource;
|
|
use App\Application\Models\User;
|
|
|
|
class UserResource extends JsonResource
|
|
{
|
|
public function toArray(): array
|
|
{
|
|
/** @var User $this->resource */
|
|
return [
|
|
'id' => $this->resource->id,
|
|
'name' => $this->resource->name,
|
|
'email' => $this->resource->email,
|
|
'created_at' => $this->resource->created_at->format('Y-m-d H:i:s'),
|
|
'updated_at' => $this->resource->updated_at->format('Y-m-d H:i:s'),
|
|
];
|
|
}
|
|
}
|
|
```
|
|
|
|
Verwenden Sie die Ressource in Ihrem Controller:
|
|
|
|
```php
|
|
use App\Application\Resources\UserResource;
|
|
|
|
public function show(Request $request, int $id): Response
|
|
{
|
|
$user = User::find($id);
|
|
|
|
if (!$user) {
|
|
return $this->json([
|
|
'error' => 'Benutzer nicht gefunden'
|
|
], 404);
|
|
}
|
|
|
|
return $this->json([
|
|
'data' => new UserResource($user)
|
|
]);
|
|
}
|
|
|
|
public function index(Request $request): Response
|
|
{
|
|
$users = User::all();
|
|
|
|
return $this->json([
|
|
'data' => UserResource::collection($users)
|
|
]);
|
|
}
|
|
```
|
|
|
|
## API-Authentifizierung
|
|
|
|
### Token-basierte Authentifizierung
|
|
|
|
Das Framework unterstützt Token-basierte Authentifizierung für APIs:
|
|
|
|
```php
|
|
namespace App\Application\Controllers\Api;
|
|
|
|
use App\Framework\Http\Controller;
|
|
use App\Framework\Http\Request;
|
|
use App\Framework\Http\Response;
|
|
use App\Framework\Auth\Auth;
|
|
use App\Framework\Auth\Token;
|
|
|
|
class AuthController extends Controller
|
|
{
|
|
public function login(Request $request): Response
|
|
{
|
|
$this->validate($request, [
|
|
'email' => 'required|email',
|
|
'password' => 'required|string',
|
|
]);
|
|
|
|
$credentials = $request->only(['email', 'password']);
|
|
|
|
if (!Auth::attempt($credentials)) {
|
|
return $this->json([
|
|
'error' => 'Ungültige Anmeldeinformationen'
|
|
], 401);
|
|
}
|
|
|
|
$user = Auth::user();
|
|
$token = Token::create($user);
|
|
|
|
return $this->json([
|
|
'data' => [
|
|
'user' => $user,
|
|
'token' => $token,
|
|
'token_type' => 'Bearer',
|
|
]
|
|
]);
|
|
}
|
|
|
|
public function logout(Request $request): Response
|
|
{
|
|
$token = $request->bearerToken();
|
|
|
|
if ($token) {
|
|
Token::revoke($token);
|
|
}
|
|
|
|
return $this->json([
|
|
'message' => 'Erfolgreich abgemeldet'
|
|
]);
|
|
}
|
|
}
|
|
```
|
|
|
|
### Authentifizierung mit dem Token
|
|
|
|
```php
|
|
namespace App\Application\Middleware;
|
|
|
|
use App\Framework\Http\Middleware;
|
|
use App\Framework\Http\Request;
|
|
use App\Framework\Http\Response;
|
|
use App\Framework\Auth\Token;
|
|
|
|
class ApiAuthMiddleware implements Middleware
|
|
{
|
|
public function handle(Request $request, callable $next): Response
|
|
{
|
|
$token = $request->bearerToken();
|
|
|
|
if (!$token || !Token::validate($token)) {
|
|
return response()->json([
|
|
'error' => 'Nicht autorisiert'
|
|
], 401);
|
|
}
|
|
|
|
$user = Token::getUser($token);
|
|
Auth::setUser($user);
|
|
|
|
return $next($request);
|
|
}
|
|
}
|
|
```
|
|
|
|
Registrieren Sie die Middleware:
|
|
|
|
```php
|
|
// In der Middleware-Konfiguration
|
|
$middleware->group('api', [
|
|
ApiAuthMiddleware::class
|
|
]);
|
|
|
|
// In den Routen
|
|
$router->group('/api', function (Router $router) {
|
|
// Öffentliche Routen
|
|
$router->post('/login', [AuthController::class, 'login']);
|
|
|
|
// Geschützte Routen
|
|
$router->group('', function (Router $router) {
|
|
$router->apiResource('users', UserController::class);
|
|
$router->post('/logout', [AuthController::class, 'logout']);
|
|
})->middleware('api');
|
|
});
|
|
```
|
|
|
|
## API-Validierung
|
|
|
|
Die Validierung für APIs funktioniert ähnlich wie für reguläre Anfragen, gibt jedoch JSON-Antworten zurück:
|
|
|
|
```php
|
|
public function store(Request $request): Response
|
|
{
|
|
$validator = new Validator($request->all(), [
|
|
'name' => 'required|string|max:255',
|
|
'email' => 'required|email|unique:users,email',
|
|
'password' => 'required|string|min:8',
|
|
]);
|
|
|
|
if ($validator->fails()) {
|
|
return $this->json([
|
|
'error' => 'Validierungsfehler',
|
|
'errors' => $validator->errors()
|
|
], 422);
|
|
}
|
|
|
|
$user = User::create($validator->validated());
|
|
|
|
return $this->json([
|
|
'data' => $user,
|
|
'message' => 'Benutzer erstellt'
|
|
], 201);
|
|
}
|
|
```
|
|
|
|
Oder mit der `validate`-Methode:
|
|
|
|
```php
|
|
public function store(Request $request): Response
|
|
{
|
|
try {
|
|
$this->validate($request, [
|
|
'name' => 'required|string|max:255',
|
|
'email' => 'required|email|unique:users,email',
|
|
'password' => 'required|string|min:8',
|
|
]);
|
|
} catch (ValidationException $e) {
|
|
return $this->json([
|
|
'error' => 'Validierungsfehler',
|
|
'errors' => $e->errors()
|
|
], 422);
|
|
}
|
|
|
|
$user = User::create($request->only(['name', 'email', 'password']));
|
|
|
|
return $this->json([
|
|
'data' => $user,
|
|
'message' => 'Benutzer erstellt'
|
|
], 201);
|
|
}
|
|
```
|
|
|
|
## API-Paginierung
|
|
|
|
Das Framework unterstützt Paginierung für API-Antworten:
|
|
|
|
```php
|
|
public function index(Request $request): Response
|
|
{
|
|
$page = $request->query('page', 1);
|
|
$perPage = $request->query('per_page', 15);
|
|
|
|
$users = User::paginate($perPage, $page);
|
|
|
|
return $this->json([
|
|
'data' => UserResource::collection($users->items()),
|
|
'meta' => [
|
|
'pagination' => [
|
|
'total' => $users->total(),
|
|
'per_page' => $users->perPage(),
|
|
'current_page' => $users->currentPage(),
|
|
'last_page' => $users->lastPage(),
|
|
]
|
|
]
|
|
]);
|
|
}
|
|
```
|
|
|
|
## API-Filterung und Sortierung
|
|
|
|
Sie können Filterung und Sortierung für Ihre API implementieren:
|
|
|
|
```php
|
|
public function index(Request $request): Response
|
|
{
|
|
$query = User::query();
|
|
|
|
// Filterung
|
|
if ($request->has('name')) {
|
|
$query->where('name', 'like', '%' . $request->query('name') . '%');
|
|
}
|
|
|
|
if ($request->has('email')) {
|
|
$query->where('email', 'like', '%' . $request->query('email') . '%');
|
|
}
|
|
|
|
if ($request->has('role')) {
|
|
$query->whereHas('roles', function ($q) use ($request) {
|
|
$q->where('name', $request->query('role'));
|
|
});
|
|
}
|
|
|
|
// Sortierung
|
|
$sortBy = $request->query('sort_by', 'created_at');
|
|
$sortDirection = $request->query('sort_direction', 'desc');
|
|
|
|
$allowedSortFields = ['id', 'name', 'email', 'created_at'];
|
|
|
|
if (in_array($sortBy, $allowedSortFields)) {
|
|
$query->orderBy($sortBy, $sortDirection === 'asc' ? 'asc' : 'desc');
|
|
}
|
|
|
|
// Paginierung
|
|
$page = $request->query('page', 1);
|
|
$perPage = $request->query('per_page', 15);
|
|
|
|
$users = $query->paginate($perPage, $page);
|
|
|
|
return $this->json([
|
|
'data' => UserResource::collection($users->items()),
|
|
'meta' => [
|
|
'pagination' => [
|
|
'total' => $users->total(),
|
|
'per_page' => $users->perPage(),
|
|
'current_page' => $users->currentPage(),
|
|
'last_page' => $users->lastPage(),
|
|
]
|
|
]
|
|
]);
|
|
}
|
|
```
|
|
|
|
## API-Rate Limiting
|
|
|
|
Das Framework bietet Rate Limiting für APIs, um Missbrauch zu verhindern:
|
|
|
|
```php
|
|
namespace App\Application\Middleware;
|
|
|
|
use App\Framework\Http\Middleware;
|
|
use App\Framework\Http\Request;
|
|
use App\Framework\Http\Response;
|
|
use App\Framework\Cache\Cache;
|
|
|
|
class RateLimitMiddleware implements Middleware
|
|
{
|
|
private int $maxRequests;
|
|
private int $timeWindow;
|
|
|
|
public function __construct(int $maxRequests = 60, int $timeWindow = 60)
|
|
{
|
|
$this->maxRequests = $maxRequests;
|
|
$this->timeWindow = $timeWindow;
|
|
}
|
|
|
|
public function handle(Request $request, callable $next): Response
|
|
{
|
|
$key = 'rate_limit:' . $this->getIdentifier($request);
|
|
$requests = Cache::get($key, 0);
|
|
|
|
if ($requests >= $this->maxRequests) {
|
|
return response()->json([
|
|
'error' => 'Zu viele Anfragen',
|
|
'message' => 'Bitte versuchen Sie es später erneut'
|
|
], 429);
|
|
}
|
|
|
|
Cache::put($key, $requests + 1, $this->timeWindow);
|
|
|
|
$response = $next($request);
|
|
|
|
$response->headers->set('X-RateLimit-Limit', $this->maxRequests);
|
|
$response->headers->set('X-RateLimit-Remaining', $this->maxRequests - $requests - 1);
|
|
|
|
return $response;
|
|
}
|
|
|
|
private function getIdentifier(Request $request): string
|
|
{
|
|
if (Auth::check()) {
|
|
return 'user:' . Auth::id();
|
|
}
|
|
|
|
return 'ip:' . $request->ip();
|
|
}
|
|
}
|
|
```
|
|
|
|
Registrieren Sie die Middleware:
|
|
|
|
```php
|
|
// In der Middleware-Konfiguration
|
|
$middleware->group('api', [
|
|
RateLimitMiddleware::class
|
|
]);
|
|
|
|
// Oder mit Parametern
|
|
$middleware->group('api', [
|
|
new RateLimitMiddleware(100, 60) // 100 Anfragen pro Minute
|
|
]);
|
|
```
|
|
|
|
## API-Dokumentation
|
|
|
|
Das Framework unterstützt die automatische Generierung von API-Dokumentation mit OpenAPI/Swagger:
|
|
|
|
```php
|
|
namespace App\Application\Controllers\Api;
|
|
|
|
use App\Framework\Http\Controller;
|
|
use App\Framework\Http\Request;
|
|
use App\Framework\Http\Response;
|
|
use App\Application\Models\User;
|
|
|
|
/**
|
|
* @OA\Tag(
|
|
* name="Users",
|
|
* description="API-Endpunkte für die Benutzerverwaltung"
|
|
* )
|
|
*/
|
|
class UserController extends Controller
|
|
{
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/users",
|
|
* summary="Liste aller Benutzer abrufen",
|
|
* tags={"Users"},
|
|
* @OA\Parameter(
|
|
* name="page",
|
|
* in="query",
|
|
* description="Seitennummer",
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
* @OA\Parameter(
|
|
* name="per_page",
|
|
* in="query",
|
|
* description="Anzahl der Elemente pro Seite",
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Erfolgreiche Operation",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="data", type="array", @OA\Items(ref="#/components/schemas/User")),
|
|
* @OA\Property(property="meta", type="object")
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function index(Request $request): Response
|
|
{
|
|
// ...
|
|
}
|
|
|
|
/**
|
|
* @OA\Get(
|
|
* path="/api/users/{id}",
|
|
* summary="Einen bestimmten Benutzer abrufen",
|
|
* tags={"Users"},
|
|
* @OA\Parameter(
|
|
* name="id",
|
|
* in="path",
|
|
* required=true,
|
|
* description="Benutzer-ID",
|
|
* @OA\Schema(type="integer")
|
|
* ),
|
|
* @OA\Response(
|
|
* response=200,
|
|
* description="Erfolgreiche Operation",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="data", ref="#/components/schemas/User")
|
|
* )
|
|
* ),
|
|
* @OA\Response(
|
|
* response=404,
|
|
* description="Benutzer nicht gefunden",
|
|
* @OA\JsonContent(
|
|
* @OA\Property(property="error", type="string")
|
|
* )
|
|
* )
|
|
* )
|
|
*/
|
|
public function show(Request $request, int $id): Response
|
|
{
|
|
// ...
|
|
}
|
|
|
|
// Weitere Methoden mit Dokumentation...
|
|
}
|
|
|
|
/**
|
|
* @OA\Schema(
|
|
* schema="User",
|
|
* required={"id", "name", "email"},
|
|
* @OA\Property(property="id", type="integer", format="int64"),
|
|
* @OA\Property(property="name", type="string"),
|
|
* @OA\Property(property="email", type="string", format="email"),
|
|
* @OA\Property(property="created_at", type="string", format="date-time"),
|
|
* @OA\Property(property="updated_at", type="string", format="date-time")
|
|
* )
|
|
*/
|
|
```
|
|
|
|
Generieren Sie die API-Dokumentation:
|
|
|
|
```bash
|
|
php console.php api:docs
|
|
```
|
|
|
|
Dies erstellt eine OpenAPI/Swagger-Dokumentation, die Sie in einem Browser anzeigen können.
|
|
|
|
## Beste Praktiken für APIs
|
|
|
|
### Versionierung
|
|
|
|
Versionieren Sie Ihre API, um Änderungen zu ermöglichen, ohne bestehende Clients zu beeinträchtigen:
|
|
|
|
```php
|
|
$router->group('/api/v1', function (Router $router) {
|
|
// API v1 Routen
|
|
});
|
|
|
|
$router->group('/api/v2', function (Router $router) {
|
|
// API v2 Routen
|
|
});
|
|
```
|
|
|
|
### Konsistente Benennung
|
|
|
|
Verwenden Sie konsistente Benennungskonventionen für Ihre API-Endpunkte:
|
|
|
|
- Verwenden Sie Substantive im Plural für Ressourcen (z.B. `/users` statt `/user`)
|
|
- Verwenden Sie Kebab-Case für URLs (z.B. `/user-profiles` statt `/userProfiles`)
|
|
- Verwenden Sie Camel-Case für JSON-Eigenschaften (z.B. `firstName` statt `first_name`)
|
|
|
|
### HTTP-Statuscodes
|
|
|
|
Verwenden Sie die richtigen HTTP-Statuscodes:
|
|
|
|
- 200 OK: Erfolgreiche Anfrage
|
|
- 201 Created: Ressource erfolgreich erstellt
|
|
- 204 No Content: Erfolgreiche Anfrage ohne Inhalt
|
|
- 400 Bad Request: Ungültige Anfrage
|
|
- 401 Unauthorized: Authentifizierung erforderlich
|
|
- 403 Forbidden: Keine Berechtigung
|
|
- 404 Not Found: Ressource nicht gefunden
|
|
- 422 Unprocessable Entity: Validierungsfehler
|
|
- 429 Too Many Requests: Rate Limit überschritten
|
|
- 500 Internal Server Error: Serverfehler
|
|
|
|
### Fehlerbehandlung
|
|
|
|
Implementieren Sie eine konsistente Fehlerbehandlung:
|
|
|
|
```php
|
|
try {
|
|
// Code, der eine Exception werfen könnte
|
|
} catch (ValidationException $e) {
|
|
return $this->json([
|
|
'error' => 'Validierungsfehler',
|
|
'errors' => $e->errors()
|
|
], 422);
|
|
} catch (AuthorizationException $e) {
|
|
return $this->json([
|
|
'error' => 'Nicht autorisiert',
|
|
'message' => $e->getMessage()
|
|
], 403);
|
|
} catch (NotFoundException $e) {
|
|
return $this->json([
|
|
'error' => 'Nicht gefunden',
|
|
'message' => $e->getMessage()
|
|
], 404);
|
|
} catch (\Exception $e) {
|
|
// Protokollieren Sie den Fehler
|
|
$this->logger->error('API-Fehler', [
|
|
'exception' => $e->getMessage(),
|
|
'trace' => $e->getTraceAsString()
|
|
]);
|
|
|
|
return $this->json([
|
|
'error' => 'Serverfehler',
|
|
'message' => 'Ein unerwarteter Fehler ist aufgetreten'
|
|
], 500);
|
|
}
|
|
```
|
|
|
|
### Dokumentation
|
|
|
|
Dokumentieren Sie Ihre API gründlich:
|
|
|
|
- Beschreiben Sie jeden Endpunkt
|
|
- Dokumentieren Sie alle Parameter
|
|
- Geben Sie Beispiele für Anfragen und Antworten
|
|
- Erklären Sie Fehlerszenarien
|
|
|
|
## Weitere Informationen
|
|
|
|
- [Routing-Anleitung](../guides/routing.md): Erfahren Sie mehr über das Routing-System.
|
|
- [Controller-Anleitung](../guides/controllers.md): Erfahren Sie mehr über Controller.
|
|
- [Validierungs-Anleitung](../guides/validation.md): Erfahren Sie mehr über die Validierung von Anfragen.
|
|
- [Sicherheits-Anleitung](../guides/security.md): Erfahren Sie mehr über die Sicherheitsfunktionen des Frameworks.
|
|
- [Architekturübersicht](../architecture/overview.md): Überblick über die Architektur des Frameworks.
|