safiahmed4cs@gmail.com's avatar

Can we use make:request feature in lumen ?

Hi folks,

I have quick doubt to clear. I have used make:request in my last laravel application.

Now i am working on the API using lumen, so i am thinking to reuse of it as i am not able to run the following command

php artisan make:request testRequest

Thanks

0 likes
5 replies
safiahmed4cs@gmail.com's avatar

Hi folks,

Sorry to disturbing again,

any update on to above query?

my aim is to use the laravel feature "FormRequest", on the fly validation.

1 like
kylesean's avatar

good question! @safiahmed4cs

I copy the FormRequest class which is in laravel to lumen and make some adjustment. just like:

<?php

namespace App\Http\Requests;

use Illuminate\Http\Request as IlluminateRequest;
use Illuminate\Http\JsonResponse;
use Illuminate\Container\Container;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Http\Exception\HttpResponseException;
use Illuminate\Validation\ValidatesWhenResolvedTrait;
use Illuminate\Contracts\Validation\ValidatesWhenResolved;
use Illuminate\Contracts\Validation\Factory as ValidationFactory;

abstract class Request extends IlluminateRequest implements ValidatesWhenResolved
{
    use ValidatesWhenResolvedTrait;

    /**
     * The container instance.
     *
     * @var \Illuminate\Container\Container
     */
    protected $container;

    /**
     * Get the validator instance for the request.
     *
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function getValidatorInstance()
    {
        $factory = $this->container->make(ValidationFactory::class);

        if (method_exists($this, 'validator')) {
            return $this->container->call([$this, 'validator'], compact('factory'));
        }

        return $factory->make(
            $this->validationData(), $this->container->call([$this, 'rules']), $this->messages(), $this->attributes()
        );
    }

    /**
     * Get data to be validated from the request.
     *
     * @return array
     */
    protected function validationData()
    {
        return $this->all();
    }

    /**
     * Handle a failed validation attempt.
     *
     * @param  \Illuminate\Contracts\Validation\Validator $validator
     * @return void
     *
     * @throws \Illuminate\Http\Exception\HttpResponseException
     */
    protected function failedValidation(Validator $validator)
    {
        throw new HttpResponseException($this->response(
            $this->formatErrors($validator)
        ));
    }

    /**
     * Get the proper failed validation response for the request.
     *
     * @param  array $errors
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function response(array $errors)
    {
        return new JsonResponse($errors, 200);
    }

    /**
     * Format the errors from the given Validator instance.
     *
     * @param  \Illuminate\Contracts\Validation\Validator $validator
     * @return array
     */
    protected function formatErrors(Validator $validator)
    {
        $codes = $validator->getMessageBag()->toArray();
        $code = current(current($codes));
        return state($code);
    }

    /**
     * Set the container implementation.
     *
     * @param  \Illuminate\Container\Container $container
     * @return $this
     */
    public function setContainer(Container $container)
    {
        $this->container = $container;

        return $this;
    }

    /**
     * Get custom messages for validator errors.
     *
     * @return array
     */
    abstract public function messages();

    abstract public function rules();

    /**
     * Get custom attributes for validator errors.
     *
     * @return array
     */
    public function attributes()
    {
        return [];
    }
}

Then I create a ServiceProvider like RequestServiceProvider, it just like FoundationServiceProvider in laravel. code like this:

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use App\Http\Requests\Request as FormRequest;
use Symfony\Component\HttpFoundation\Request;
use Illuminate\Contracts\Validation\ValidatesWhenResolved;
class RequestServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->configureFormRequests();
    }

    protected function configureFormRequests()
    {

        $this->app->afterResolving(function (ValidatesWhenResolved $resolved) {
            $resolved->validate();
        });

        $this->app->resolving(function (FormRequest $request, $app) {
            $this->initializeRequest($request, $app['request']);
        });
    }

    /**
     * Initialize the form request with data from the given request.
     *
     * @param  \App\Http\Requests\FormRequest  $form
     * @param  \Symfony\Component\HttpFoundation\Request  $current
     * @return void
     */
    protected function initializeRequest(FormRequest $form, Request $current)
    {
        $files = $current->files->all();

        $files = is_array($files) ? array_filter($files) : $files;

        $form->initialize(
            $current->query->all(), $current->request->all(), $current->attributes->all(),
            $current->cookies->all(), $files, $current->server->all(), $current->getContent()
        );

        $form->setContainer($this->app);

    }
}

OK,don't forget register this ServiceProvider in bootstrap/app.php:

$app->register(App\Providers\RequestServiceProvider::class);

So I can make a Request directory to store my defined request:

<?php
namespace App\Http\Requests\Test;

use App\Http\Requests\Request;

class TestRequest extends Request

{
    public function rules()
    {
        return [
           
        ];
    }

    public function messages()
    {
        return [
          
        ];
    }
}

Hope can help you!

2 likes
mikimaine's avatar

every thing works from the above solution but you should change

use Illuminate\Http\Exception\HttpResponseException;

to

use Illuminate\Http\Exceptions\HttpResponseException;

since Exception has been changed to plural.

CrazyZard's avatar

Uncaught TypeError: Argument 1 passed to App\Providers\RequestServiceProvider::App\Providers{closure}() must be an instance of App\Http\Requests\Request, instance of App\Exceptions\Handler given, called in app\Providers\RequestServiceProvider.php on line 27

line 27 : $this->app->resolving(function (FormRequest $request, $app) { $this->initializeRequest($request, $app['request']); }); Have you ever had this problem?

kylesean's avatar

@CRAZYZARD - This method is about version 5.2。Laravel may changed some of these code gists。You shoud compare them,and chose right code gists correspondly。

Please or to participate in this conversation.