nepster's avatar

API on laravel 11

So I decided to use Laravel 11 for my new application (why not). And I'm a little confused with api requests.

I configurate my app (I have only api cases):

return Application::configure(basePath: dirname(__DIR__))
    ->withProviders([
        ...(require __DIR__ . '/providers.php'),
    ],
        false
    )
    ->withCommands([ __DIR__ . '/Command'])
    ->withRouting(
        api: __DIR__ . '/routes.api.php',
        apiPrefix: ''
    )
    ->withExceptions(function (Exceptions $exceptions): void {
        $exceptions->renderable(function (\Throwable $throwable): JsonResponse {
            return handleApiException($throwable);
        });
    })
    ->create();

but, but I feel that my application does not understand that it is an api.

I recieve this error: Route [login] not defined.

Do you remember there used to be a middleware Authenticate that was available in the skeleton? I used to do this:

class Authenticate extends Middleware
{
    protected function redirectTo(Request $request): ?string
    {
        if (str_starts_with($request->getUri(), config('app.api_url'))) {
            return null;
        }

        if ($request->expectsJson() === false) {
            return route('login');
        }

        return null;
    }
}

but now this middleware is hidden in the core.

So if my requests do not use special json headers, then the application does not understand that this is an api.

I can make some kind of workaround:

    $request->headers->add([
        'Accept' => '.../json',
    ]);

this will solve the problem, but something tells me that it wasn’t intended that way.

0 likes
8 replies
Snapey's avatar

did you mean to write '/routes/api.php'

1 like
nepster's avatar

@Snapey, no, I didn't reconfigure the structure much.

I only need one route file without folder and I moved the bootstrap folder. I don't understand what it does in the root of the project.

puklipo's avatar

Laravel 11 is not yet released

// bootstrap/app.php

use Illuminate\Foundation\Application;
use Illuminate\Foundation\Configuration\Exceptions;
use Illuminate\Foundation\Configuration\Middleware;
use Illuminate\Http\Request;

return Application::configure(basePath: dirname(__DIR__))
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->redirectTo(guests: function (Request $request){
            //
        });
    })
1 like
nepster's avatar

@puklipo, but soon I don't think there will be too many changes yet.

Thanks for the tip, now I understand the principle a little better.

martinbean's avatar

@nepster If you only want to respond to AJAX requests, then register a middleware that enforces that:

public function handle(Request $request, Closure $next)
{
    if ($request->expectsJson()) {
        return $next($request);
    }

    abort(406);
}

This will throw a 406 Not Acceptable response unless the user specifies Accept: application/json in request headers.

1 like
jekinney's avatar

I know OP hasn't come back to respond BUT Laravel has amazing tools built in to deal with API's. Many and many tutorials here to help you.

In Laravel 11 and using the installer it should ask you if your building an API.

Otherwise read the docs on how to publish the API route file (was available by default in Laravel 10 and below). Using the API routes (default to http://localhost.com/api/ ) will auto magically set up request headers.

When your ready, Laravel also has some CORS configuration built in. Laravel also has api resources to help filter out unwanted data before sending the response. Documented very well and should be easy to follow.

1 like

Please or to participate in this conversation.