Laravel Scout Search With the HTTP QUERY Method | Mohamed Said       [Skip to content](#main)  [ ![](https://cdn.msaied.com/01KT78WE565VEMM3PSNQAAB0MH.png) Mohamed SaidLaravel Backend Engineer ](https://www.msaied.com/public) - [Home](https://www.msaied.com/public)
- [Projects](https://www.msaied.com/public/projects)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [About](https://www.msaied.com/public#about)

           [  Contact](https://www.msaied.com/public#contact) Menu 

Menu
----

Close 

 - [HomeStart here](https://www.msaied.com/public)
- [ProjectsCase studies](https://www.msaied.com/public/projects)
- [ArticlesEngineering notes](https://www.msaied.com/public/articles)
- [CertificatesCredentials](https://www.msaied.com/public/certificates)
- [AboutHow I work](https://www.msaied.com/public#about)
- [ContactGet in touch](https://www.msaied.com/public#contact)

  [Start a conversation](https://www.msaied.com/public#contact) [WhatsApp](https://wa.me/201094619204) [Email](mailto:hello@msaied.com) 

 1. [Home](https://www.msaied.com/public)
2. /
3. [Articles](https://www.msaied.com/public/articles)
4. /
5. [Laravel](https://www.msaied.com/public/articles?category=laravel)
6. /
7. Build a Laravel Scout Search Endpoint With the HTTP QUERY Method

   [Laravel](https://www.msaied.com/public/articles?category=laravel) 

 Build a Laravel Scout Search Endpoint With the HTTP QUERY Method
=================================================================

 Learn how to register an HTTP QUERY route in Laravel 13 using Route::match(), back it with Laravel Scout's database driver, and test it with the queryJson() helper added in Laravel 13.19.

 ![](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp) [Mohamed Said](https://www.msaied.com/public#person) Published 16 Jul 2026 · Updated 16 Jul 2026 · 3 min read

ShareCopy linkCopied

 ![Build a Laravel Scout Search Endpoint With the HTTP QUERY Method](https://cdn.msaied.com/433/f1100f27bf9bb41032e0ea927629e818.png) 

  On this page +1. [What Is the HTTP QUERY Method?](#what-is-the-http-query-method)
2. [Setting Up Scout](#setting-up-scout)
3. [Defining a QUERY Route](#defining-a-query-route)
4. [Testing the Endpoint](#testing-the-endpoint)
5. [CSRF and Web Routes](#csrf-and-web-routes)
6. [Gotchas Before You Ship](#gotchas-before-you-ship)
7. [Key Takeaways](#key-takeaways)

 What Is the HTTP QUERY Method?
------------------------------

The HTTP QUERY method ([RFC 10008](https://www.rfc-editor.org/rfc/rfc10008)) is a safe, cacheable HTTP verb designed specifically for queries. Like GET, it signals a read-only operation—but it carries its parameters in the request body, avoiding URL length limits and keeping sensitive values out of access logs and browser history.

Laravel 13.19 added `Http::query()` to the HTTP client and `queryJson()` / `query()` testing helpers. A first-class `Route::query()` helper is already merged for Laravel 14, but you can use `Route::match()` today to register QUERY routes in Laravel 13.

Setting Up Scout
----------------

Start from a fresh Laravel 13 app and install the API routes file and Scout:

```bash
php artisan install:api
composer require laravel/scout

```

Set the database driver in `.env`—no external search service required:

```env
SCOUT_DRIVER=database

```

Create an `Article` model with migration and factory:

```bash
php artisan make:model Article -mf

```

Add the `Searchable` trait and define `toSearchableArray()`:

```php
use Laravel\Scout\Searchable;

class Article extends Model
{
    use HasFactory, Searchable;

    protected $fillable = ['title', 'body'];

    public function toSearchableArray(): array
    {
        return ['title' => $this->title, 'body' => $this->body];
    }
}

```

Defining a QUERY Route
----------------------

In `routes/api.php`, register the route with `Route::match()`:

```php
Route::match(['QUERY'], '/articles/search', function (Request $request) {
    $validated = $request->validate([
        'search'   => ['required', 'string'],
        'per_page' => ['sometimes', 'integer', 'between:1,50'],
    ]);

    return Article::search($validated['search'])
        ->paginate($validated['per_page'] ?? 15);
});

```

Validation and `$request->input()` read from the JSON body exactly as they would for a POST request. Running `php artisan route:list` confirms the verb:

```
QUERY  api/articles/search

```

A raw request looks like this:

```http
QUERY /api/articles/search HTTP/1.1
Content-Type: application/json
Accept: application/json

{"search": "scout", "per_page": 10}

```

Testing the Endpoint
--------------------

Laravel 13.19's `queryJson()` helper makes tests feel identical to `postJson()`:

```php
$this->queryJson('/api/articles/search', ['search' => 'scout'])
    ->assertOk()
    ->assertJsonCount(1, 'data')
    ->assertJsonPath('data.0.title', 'Getting Started With Laravel Scout');

```

On the client side, use `Http::query()`:

```php
$response = Http::acceptJson()->query('https://example.com/api/articles/search', [
    'search' => 'scout',
]);

```

CSRF and Web Routes
-------------------

API routes skip CSRF automatically. For `routes/web.php`, Laravel 13's `PreventRequestForgery` middleware treats QUERY like POST and returns a `419`. Extend the middleware to backport Laravel 14's behavior:

```php
protected function isReading($request)
{
    return in_array($request->method(), ['HEAD', 'GET', 'OPTIONS', 'QUERY']);
}

```

Swap it in `bootstrap/app.php` and delete the override after upgrading to Laravel 14.

Gotchas Before You Ship
-----------------------

- **PHP's built-in server** returns `501 Not Implemented` for QUERY—use Herd, Valet, or test helpers instead.
- **CDNs, WAFs, and load balancers** may block unrecognized verbs; test the full request path.
- **CORS preflight** is required for every cross-origin QUERY request—it is not a safelisted method.
- **Caching** is defined by the RFC but not yet implemented by browsers or CDNs.
- **OpenAPI 3.2** added a first-class `query` operation; toolchains targeting 3.0/3.1 cannot describe the endpoint yet.

Key Takeaways
-------------

- `Route::match(['QUERY'], ...)` registers QUERY routes in Laravel 13 today.
- Scout's database driver requires no external service and works out of the box.
- `queryJson()` in Laravel 13.19 makes feature-testing QUERY endpoints straightforward.
- Laravel 14 will add `Route::query()` and exempt QUERY from CSRF automatically.
- QUERY is best suited to internal APIs where you control both client and server.

---

Source: [Build a Laravel Scout Search Endpoint With the HTTP QUERY Method](https://laravel-news.com/build-a-laravel-scout-search-endpoint-with-the-http-query-method)

- [Laravel](https://www.msaied.com/public/articles?search=Laravel)
- [Laravel Scout](https://www.msaied.com/public/articles?search=Laravel%20Scout)
- [HTTP QUERY](https://www.msaied.com/public/articles?search=HTTP%20QUERY)
- [REST API](https://www.msaied.com/public/articles?search=REST%20API)
- [PHP](https://www.msaied.com/public/articles?search=PHP)
- [Laravel 13](https://www.msaied.com/public/articles?search=Laravel%2013)

 Frequently asked questions 
---------------------------

  Can I use the HTTP QUERY method in Laravel 13 before Route::query() is available?Yes. Laravel 13's router accepts any HTTP verb via Route::match(). Register your route with Route::match(\['QUERY'\], '/path', $handler) and it works today. The dedicated Route::query() shorthand is coming in Laravel 14.

   Why does PHP's built-in server return 501 for QUERY requests?PHP's built-in server hard-codes the HTTP methods it accepts and does not recognize QUERY, so it returns 501 Not Implemented before the request reaches Laravel. Use Nginx-based environments like Laravel Herd or Valet, or rely on Laravel's HTTP testing helpers, which dispatch requests directly through the framework.

   Do QUERY routes in routes/web.php require CSRF handling?Yes, in Laravel 13 the PreventRequestForgery middleware treats QUERY like POST and will return a 419. You can extend the middleware to add QUERY to its list of read verbs, or exclude individual routes with withoutMiddleware(). Laravel 14 will exempt QUERY automatically.

   ![Mohamed Said](https://cdn.msaied.com/01M22N44A70A5MC2S599JP0MPH.webp)About the author
----------------

[Mohamed Said](https://www.msaied.com/public#person)Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

[About](https://www.msaied.com/public#about) [GitHub ↗](https://github.com/EG-Mohamed) [LinkedIn ↗](https://www.linkedin.com/in/msaiedm/) [WhatsApp ↗](https://wa.me/201094619204) [Email Address ↗](mailto:hello@msaied.com) [My CV ↗](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)  

   [Previous articleEnforce Per-Action Waiting Periods in Laravel with the Cooldown Package](https://www.msaied.com/public/articles/enforce-per-action-waiting-periods-in-laravel-with-the-cooldown-package) [Next articleFilament v5 Preview: Schema Unification, Performance Shifts, and How to Prepare](https://www.msaied.com/public/articles/filament-v5-preview-schema-unification-performance-shifts-and-how-to-prepare-1)  

   On this page
-------------

1. [What Is the HTTP QUERY Method?](#what-is-the-http-query-method)
2. [Setting Up Scout](#setting-up-scout)
3. [Defining a QUERY Route](#defining-a-query-route)
4. [Testing the Endpoint](#testing-the-endpoint)
5. [CSRF and Web Routes](#csrf-and-web-routes)
6. [Gotchas Before You Ship](#gotchas-before-you-ship)
7. [Key Takeaways](#key-takeaways)

 ###  Have a technical challenge?

 Tell me what you’re building. I reply within two working days.

[Start a conversation](https://www.msaied.com/public#contact) 

   Related articles
-----------------

 [ ![](https://cdn.msaied.com/743/8998fac3a41451ab3fe1588194e17a43.png) Filament · 3 min read### Securing Filament Plugins with Plumb: Automated Security Scoring for PHP Packages

5 Oct 2026 ](https://www.msaied.com/public/articles/securing-filament-plugins-with-plumb-automated-security-scoring-for-php-packages) [ ![](https://cdn.msaied.com/742/2d02018669cdeedccb5de2efb898f0ee.png) Filament · 3 min read### Filament v3.3.56 Released: File Hash Names and Livewire Upload Fix

5 Oct 2026 ](https://www.msaied.com/public/articles/filament-v3356-released-file-hash-names-and-livewire-upload-fix) [ ![](https://cdn.msaied.com/741/5b55c123ad08e4d34e1f4b99ad6a428b.png)  · 3 min read### Filament v4 Schema-Based Forms, Infolists, and the Unified Schema API

5 Oct 2026 ](https://www.msaied.com/public/articles/filament-v4-schema-based-forms-infolists-and-the-unified-schema-api-5) 

  Have a technical challenge?
----------------------------

Tell me what you’re building. I reply within two working days.

 [Discuss your project ↗](https://www.msaied.com/public#contact) 

  © 2026 Mohamed Said · Built with Laravel, meant to last.Senior Backend Engineer specializing in Laravel, scalable SaaS platforms, APIs, and cloud infrastructure. I build secure, high-performance web applications that help businesses grow.

 - [Home](https://www.msaied.com/public)
- [Articles](https://www.msaied.com/public/articles)
- [Certificates](https://www.msaied.com/public/certificates)
- [GitHub](https://github.com/EG-Mohamed)
- [LinkedIn](https://www.linkedin.com/in/msaiedm/)
- [WhatsApp](https://wa.me/201094619204)
- [Email Address](mailto:hello@msaied.com)
- [My CV](https://drive.google.com/file/u/0/d/1MF20IPRJyzfy32mhEutjL5EpSls0w2Q8/view)
- [Sitemap](https://www.msaied.com/public/sitemap.xml)
