A
A
Alexey Nikolaev2019-02-17 13:32:18
Laravel
Alexey Nikolaev, 2019-02-17 13:32:18

How to validate route parameters, or how to replace the native Request class with your own?

Good day.
I have an Account entity that various other entities can refer to. For example, Post. CRUD for Posts looks something like this:
/accounts/{account}/posts/{post}
Accordingly, I check in the controller code whether the Post belongs to the transferred Account or not. If not, I generate an error. This code is repeated from method to method, and I want to put it in a separate validation rule.
However, there is a problem: Laravel does not provide the ability to validate route parameters. StackOverflow recommends overloading the all() method of the Request object, which I did by creating my own App\Http\Request class. However, after that, the DI container fell off: it injects my own Request into the controller methods instead of Lara's native request, but without data inside. Actually, the code of my Request and the controller is under the spoiler.

Request and controller code
namespace App\Http;

use Illuminate\Http\Request as NativeRequest;

class Request extends NativeRequest
{
    public function all($keys = null)
    {
        $results = parent::all($keys);
        // тут бы еще подмешивал route->parameters

        return $results;
    }
}

I'm trying to inject my own Request, but it's empty.
use App\Http\Request;

class PostsController extends Controller
{
    public function update(Request $request, int $accountId, int $postId)
    {
        return $request->all(); // пусто, при этом POST есть. все работает, если вернуть нативный реквест
    }
}

How to be? There are two questions, depending on the feasibility of each of them.
1. What is the best way to validate route parameters if you really need to?
2. How can I replace the native Illuminate\Http\Request with my own App\Http\Request so that this class is injected correctly?

Answer the question

In order to leave comments, you need to log in

2 answer(s)
A
Alex Wells, 2019-02-17
@Alex_Wells

Here is a snippet from my project. Actually, I don’t use regular requests at all, and all validation is always in FormRequest, so this suits me. Validate as usual - in rules, the most common rules, only the names of the parameters must begin with { and end with } - this is just in case, so as not to accidentally mix different parameters.

use Illuminate\Foundation\Http\FormRequest;

abstract class Request extends FormRequest
{
    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    protected function validationData()
    {
        return $this->all() + $this->routeParameters();
    }

    /**
     * Get route parameters for this request and wrap them into {} each.
     *
     * @return array
     */
    protected function routeParameters()
    {
        return collect($this->route()->parameters)
            ->mapWithKeys(function ($item, $key) {
                return ['{'.$key.'}' => $item];
            })
            ->toArray();
    }
}

T
Tronyx, 2019-06-02
@Tronyx

In the RouteServiceProvider file, add the following

public function boot() {
    // Кастомные патерны для проверки переменных в имени роута
    // Если не соответствует регулярке - то не будет выполнен запрос к контроллеру
    Route::pattern('slug', SlugRule::$regexp);
    Route::pattern('id', '\d+');
    parent::boot();
  }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question