I’ve just test the API using Postman. When I don’t using sub-directory, the API works fine like this
But if I using sub-directory, it returns 404 Not Found, like this, even I configure nano/etc/nginx/sites-available/mobilku
by adding this line following this link :
Config nginx for Laravel In a subfolder
location /mobilku {
alias var/www/html/mobilku/public;
try_files $uri $uri/ /index.php$args;
location ~ .php$ {
include snippet/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}
}
the output when I using subfolder it return like this
the question is, how to make API routes from subfolder still works like picture in above?
Here is my example code for get car using API
Route::prefix('car')->group(function () {
Route::get('/', [CarController::class, 'all'])->name('car');
Route::get('/details/{id}', [CarController::class, 'details'])->name('car.detail');
Route::post('/search', [CarController::class, 'search'])->name('car.search');
Route::post('/filter', [CarController::class, 'filter'])->name('car.filter');
});
I just read this link Laravel routes not working with subfolder, but I’m not sure that answer still works for Laravel 8 and 9.
2
Answers
laravel web app configuration
According to the laravel v8 and v9 documentation, there are no big changes from the laravel v5 (besides that your routes should now start with the
/
prefix unlike it was in v5). Both answers from the referred thread also suggests to use aRouteServiceProvider
(v8, v9) to define such a prefix globally.However when you place your app under an additional URI prefix, it will see all the routes as
/mobilku/api/...
rather than/api/...
, so you should change some other code part of your laravel app that you didn’t show in your question to made it ready for such a change (or you can somewhat "spoof" the URI it will see from it’s side; see the last part of the answer). You may also consider to just rename an/api
URI prefix to the/mobilku
one.nginx configuration
Serving a PHP web app under an URI prefix using the
alias
directive is a bit tricky due the the long standing side effects of thetry_files
directive used together with thealias
one, which are unlikely to be fixed at least until the major nginx version gets changed since there are too many configurations exists adopted to those effects in some way. Commonly used workarounds are:duplicating the
try_files
directive last argument prefix:using an
if
instead of thetry_files
:using an additional named location as the
try_files
directive last argument:However none of those workarounds are needed when you are serving an API web app that doen’t have any static files at all, and any incoming request should be served by the
index.php
controller. The much more efficient way, without traversing the request though different location, checking the static files existence and matching an URI against the.php$
regex pattern (invoking an expensive PCRE library call) will be the following:Spoofing a request URI that will be seen by the laravel app
An original request URI seen by laravel application is passed to the PHP-FPM backend via the
REQUEST_URI
FastCGI variable, which is being defined inside thefastcgi_params
file asIf for some reason you can’t change your backend laravel (or any other PHP based) web app, you still can change the
REQUEST_URI
FastCGI variable value that is being passed to the backend.That
$request_uri
is an internal read-only nginx variable, so you can’t change its value usingset
directive. However you can redefine its value after it will be defined inside thefastcgi_params
file. The PHP-FPM FastCGI backend will use the last defined value (although other FastCGI backends can behave differently; you can check this ServerFault thread to find out more some details). To strip the/mobilku
URI prefix from theREQUEST_URI
FastCGI variabe you can use an additionalrewrite
directive:or the following one to replace the
/mobilku
prefix with the/api
:However it can be unreliable if your original URI contain some characters that are getting url-decoded during the URI normalization process (for example, some special characters or two bytes UTF-8 characters from national alphabets) because the
rewrite
directive (as well as thelocation
one) works with the normalized URI while a PHP backend expect to see an url-encoded one. A more reliable way would be to use amap
block to strip or replace URI prefix, e.g.or
Then you can use a mapped
$tweaked_uri
variable the same way as shown in the previous example:The Laravel application understands that it is at the root of the server by default.
Try this, I hope it helps you:
source: https://lucabecchetti.medium.com/configure-laravel-to-work-in-a-subdirectory-and-with-artisan-serve-at-the-same-time-654ba0c1fd0b
Add APP_DIR environment variable to your .env file, containing the subdirectory where Laravel is installed into, like showed below:
Then create a Helper Provider to define our custom functions, create a file HelperServiceProvider.php inside Providers directory, with the following code:
Then, at the level of App directory, add Helpers directory, and inside it, create a file SubdirectoryAssetsHelper.php, with the following code:
Now register the provider by adding this line to config/app.php file:
Now replace the function mapWebRoutes of file RouteServiceProvider.php, like showed below:
And import App class in top of file:
use App;
That’s all, now you can use function subdirAsset instead of asset and subdirMix instead of mix inside your blade files.
Switch environment
If you are using valet or artisan serve, keep your APP_ENV variable to “local”:
If you are in a production environment of shared hosting, use: