Api: Internal requests do NOT work properly

Created on 10 May 2016  路  15Comments  路  Source: dingo/api

Add the following to your routes.php

$api = app('Dingo\Api\Routing\Router');
$api->version('v1', function ($api) {
    $api->resource('recipe', 'App\Http\Controllers\IndexController');
});

Add, edit or replace the following two methods in your IndexController

class IndexController extends Controller
{
    use Helpers;
    public function index()
    {
        $dispatcher = app('Dingo\Api\Dispatcher');

        try {
            $response = $dispatcher->with(
                [
                    'title'        => '!!!',
                    'description'  => '',
                    'lng_code'    => 'en'
                ])->post('recipe');
        }
        catch (Exception $e)
        {
            debug($e);
        }
    }

    public function store(StoreRecipeRequest $request)
    {
        return $request->get('title');
    }
}

Create the following file named StoreRecipeRequest.php in app\Http\Requests\

<?php
namespace App\Http\Requests;
use App\Http\Requests\Request;

class StoreRecipeRequest extends \Dingo\Api\Http\FormRequest
{
    /**
     * Determine if the user is authorized to make this request.
     *
     * @return bool
     */
    public function authorize()
    {
        return true;
    }

    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'title'         => 'required|string|max:128',
            'description'   => 'string',
            'lang_code'     => 'required|max:2'
        ];
    }
}

Now, using (for example) Postman to call the store() method with the same data being passed in as in the Controller's index() function, the results returned are as expected.

{
  "message": "422 Unprocessable Entity",
  "errors": {
    "lang_code": [
      "The lang code field is required."
    ]
  },
  "status_code": 422,.....

However, if you try to run the controller's index() function, you'll see this: ValidationHttpException in FormRequest.php line 22:

Removing the type hinting from the store() method (so that no more FormRequest is executed), and manually writing the validation logic in the store() method, like so:

    public function store(\Illuminate\Http\Request $request)
    {
        $this->validate($request, [
            'title'         => 'required|string|max:128',
            'description'   => 'string',
            'lang_code'     => 'required|max:2'
        ]);
    }

does NOT work either, this time throwing the following: InternalHttpException in Dispatcher.php line 543:

Am I doing it wrong?

bug duplicate planned

Most helpful comment

+1

All 15 comments

Also watch #1014

Still no update or at least confirmation of this issue?

I would also like to know if this is getting fixed soon, it is keeping me from using this package.

@datune I think you have a typo in your IndexController:

$response = $dispatcher->with( [ 'title' => '!!!', 'description' => '', 'lng_code' => 'en' ])->post('recipe');

Should lng_code be lang_code ?

@jayhealey It's a typo on purpose, in order to trigger the validator...

still not fixed? :(

Any ideas how to fix this yet ?

+1

Gonna add this to the list of issues I need to address, once I finished getting caught up and going through the backlog of issues.

@datune So looked into this, is the issue you're having that calling a FormRequest validated route internally throws the ValidationHttpException exception? But when you call the endpoint externally (like through Postman), it correctly renders a JSON response?

@hskrasek

Thanks for looking into it, been waiting a long time. To answer your question, yes, externally calling the API works as expected, but internal requests throw exceptions.

@datune No worries. So the fact that internal requests throws an exception, in this case, during validation is by design. Since you're internally calling the API, this gives you the power to control what happens in an error case.

Think of it as using Guzzle to call your own API, you'd probably try/catch the Guzzle call, and handle the exception accordingly.

If you want the response from validation failures to be returned, you could remove the try/catch, which will let the exception be handled and rendered by Dingo's handler.

@hskrasek

This can't be by design, since the exception can not be catched! Give it a try and you'll see what I mean.

@datune If you look at the test here, you can see that any exception that extends HttpException does in fact fall through the router https://github.com/dingo/api/blob/master/tests/DispatcherTest.php#L160-L177. This is only for internal requests though.

Should also make sure your FormRequest objects are extending Dingo's and not Laravels.

Please see my comment at: https://github.com/dingo/api/issues/998#issuecomment-242742171

Was this page helpful?
0 / 5 - 0 ratings

Related issues

sukh-gill picture sukh-gill  路  3Comments

adrian-fjellberg picture adrian-fjellberg  路  4Comments

yanguanglan picture yanguanglan  路  3Comments

Sogl picture Sogl  路  4Comments

jhayiwg picture jhayiwg  路  3Comments