Code Integration Guide
Integrate the native Gemini HTTP client into your Laravel application in four simple steps. Zero external packages required.
1 Environment Setup
Add your Google Gemini API key to your .env file. You can generate one from Google AI Studio.
.env
GEMINI_API_KEY=your_api_key_here
GEMINI_DEFAULT_MODEL=gemini-2.5-flash
2 The Service Class
Create a centralized service class. This keeps our controllers clean and handles the native HTTP payload assembly for both text and images.
app/Services/GeminiService.php
<?php
namespace App\Services;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
use Exception;
class GeminiService
{
protected string $apiKey;
protected string $model;
protected string $baseUrl = 'https://generativelanguage.googleapis.com/v1beta';
public function __construct()
{
$this->apiKey = env('GEMINI_API_KEY');
$this->model = env('GEMINI_DEFAULT_MODEL', 'gemini-2.5-flash');
}
public function generateText(string $prompt): string
{
$payload = ['contents' => [['parts' => [['text' => $prompt]]]]];
return $this->sendRequest($payload);
}
public function analyzeImage(string $path, string $prompt, string $mime): string
{
$bytes = Storage::disk('local')->get($path);
$payload = [
'contents' => [[
'parts' => [
['text' => $prompt],
['inline_data' => ['mime_type' => $mime, 'data' => base64_encode($bytes)]]
]
]]
];
return $this->sendRequest($payload);
}
protected function sendRequest(array $payload): string
{
$url = "{$this->baseUrl}/models/{$this->model}:generateContent?key={$this->apiKey}";
$response = Http::timeout(30)->retry(2, 500)->post($url, $payload);
if ($response->failed()) {
throw new Exception("API Error: " . $response->json('error.message'));
}
return $response->json('candidates.0.content.parts.0.text', '');
}
}
3 Controller Implementation
Inject the GeminiService into your controller. Handle basic validation and temporary file storage for images.
app/Http/Controllers/GeminiController.php
<?php
namespace App\Http\Controllers;
use App\Services\GeminiService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
class GeminiController extends Controller
{
public function __construct(protected GeminiService $gemini) {}
public function generate(Request $request)
{
$request->validate(['prompt' => 'required|string']);
return response()->json([
'message' => $this->gemini->generateText($request->prompt)
]);
}
public function analyze(Request $request)
{
$request->validate([
'prompt' => 'required|string',
'image' => 'required|image'
]);
$path = $request->file('image')->store('temp');
$mime = $request->file('image')->getMimeType();
$analysis = $this->gemini->analyzeImage($path, $request->prompt, $mime);
Storage::disk('local')->delete($path); // Cleanup
return response()->json(['analysis' => $analysis]);
}
}
4 API Routes
Finally, register the endpoints. These URLs are consumed by the jQuery AJAX calls in your Blade frontend.
routes/api.php
use App\Http\Controllers\GeminiController;
use Illuminate\Support\Facades\Route;
Route::post('/ai/generate', [GeminiController::class, 'generate']);
Route::post('/ai/analyze-image', [GeminiController::class, 'analyze']);