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']);