Ad

Laravel 5: API Routes + Wildcard Route Results In Unexpected Behavior

I am trying to build a React application backed with Laravel API, so essentially using a wildcard route for client-side routing, and then simply an API route group to process data.

This is my routes/web.php file:

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/payment/redirect/{orderId}', ['as' => 'mollie.redirect', 'uses' => '[email protected]']);
Route::get('/{any}', ['as' => 'index', 'uses' => '[email protected]'])->where('any', '.*');

And this is my routes/api.php file:

<?php

use Illuminate\Http\Request;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::post('/orders', ['as' => 'orders.store', 'uses' => '[email protected]']);
Route::post('/payment/webhook', ['as' => 'mollie.webhook', 'uses' => '[email protected]']);

which results in:

enter image description here

But, whenever I try to make a request at POST api/orders this is what I get in Postman:

enter image description here

Which is what [email protected] should respond, not [email protected], which should be a JSON response.

This is my OrdersController code:

<?php 

namespace Http\Controllers;

use Customer;
use Http\Requests\OrderCreateRequest;
use Order;
use Product;
use Services\CountryDetector;
use Services\LanguageService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Route;

class OrdersController extends Controller
{
    const ERROR_PRODUCT_COUNTRY_UNAVAIALBLE = 'errors.products.country_unavailable';

    public function store(OrderCreateRequest $request, LanguageService $language, Order $orders, Customer $customers, Product $products)
    {
        $customer = $customers->firstOrCreate(['email' => $request->input('customer.email')], [
            'name' => $request->input('customer.fullname'),
            'email' => $request->input('customer.email'),
            'phone' => $request->input('customer.phone'),
            'country' => $language->getCurrentCountry(),
            'company_name' => $request->input('customer.company_name'),
            'city' => $request->input('customer.city'),
            'optin_newsletter' => $request->input('customer.newsletter')
        ]);

        $product = $products->find($request->input('cart.product_id'));

        $pricing = $product->getCountryPrice($language->getCurrentCountry());

        if (! $pricing)
        {
            return response()->json([
                'error' => trans(self::ERROR_PRODUCT_COUNTRY_UNAVAILABLE, ['productName' => $product->name])
            ], 422);
        }

        $order = $orders->create([
            'customer_id'        => $customer->id,
            'product_id'         => $product->id,
            'product_flavor'     => $request->input('cart.flavor'),
            'amount'             => $pricing->amount,
            'vat_amount'         => $pricing->vat_amount,
            'currency'           => $pricing->currency,
            'carehome_selection' => $request->input('carehome.custom'),
            'carehome_name'      => $request->input('carehome.name'),
            'carehome_type'      => $request->input('carehome.type'),
            'carehome_address'   => $request->input('carehome.address'),
            'carehome_city'      => $request->input('carehome.city'),
            'carehome_notes'     => $request->input('carehome.notes'),
            'custom_message'     => $request->input('gifting_options.message'),
            'is_anonymous'       => $request->input('gifting_options.anonymous'),
            'wants_certificate'  => $request->input('gifting_options.certificate'),
            'status'             => Order::STATUS_PENDING,
            'type'               => $request->input('payment_type')
        ]);

        $mollie = $order->getOrCreateMollie();

        return response()->json([
            'mollie_redirect' => $mollie->getCheckoutUrl()
        ]);
    }
}

Also, if I try to remove the API routes temporarily, and still attempt to access them, I weirdly enough get a 404, which means Laravel is able to detect the route, but it's using the wrong Controller's response.

How do I fix this?

Ad

Answer

Similar to what @Marcin Nabialek said, it was an issue with one of the headers that should have supposedly been sent with the request. However it was not the Content-Type but rather Accept.

You must use Accept: application/json in order to receive a JSON response for APIs, at least this is how it behaves in Laravel 5.7.6.

Ad
source: stackoverflow.com
Ad