path() === '/api/mini' || str_starts_with($request->path(), '/api/mini/'); } public static function requestId(Request $request): string { return $request->miniRequestId ??= bin2hex(random_bytes(16)); } public static function success(Request $request, mixed $data): Response { return self::make($request, 200, 0, 'ok', $data); } public static function error(Request $request, ApiException $error): Response { $response = self::make( $request, $error->status, $error->getCode(), $error->getMessage(), $error->fields ? ['fields' => $error->fields] : null ); if (in_array($error->status, [429, 503], true) && isset($error->fields['retry_after'])) { $response->withHeader('Retry-After', (string) max(1, (int) $error->fields['retry_after'])); } return $response; } private static function make(Request $request, int $status, int $code, string $message, mixed $data): Response { $id = self::requestId($request); return new Response( $status, [ 'Content-Type' => 'application/json; charset=utf-8', 'Cache-Control' => 'no-store', 'X-Request-Id' => $id, 'X-Content-Type-Options' => 'nosniff', ], json_encode([ 'code' => $code, 'message' => $message, 'data' => $data, 'request_id' => $id, ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_INVALID_UTF8_SUBSTITUTE | JSON_THROW_ON_ERROR) ); } }