Artur Majchrzak
Artur Majchrzak

Reputation: 113

How to return custom JSON array name and elements inside when validating in Lumen 7?

i am trying to return JSON of validation error messages in Lumen 7.2.1

At the moment Postman returns me this:

{
    "last_name": [
        "Pole zawiera niepoprawne znaki"
    ],
    "email": [
        "Email jest już zajęty"
    ]
}

I would like to return something like this:

{
    errors: [
        "last_name": [
            "Pole zawiera niepoprawne znaki"
        ],
        "email": [
            "Email jest już zajęty"
        ]
    ]
}

This is my update method in controller:

    /**
     * Update user
     *
     * @param Request $request
     * @param $id
     * @return JsonResponse
     * @throws ValidationException
     */
    public function update(Request $request, $id)
    {
        //validate incoming request
        $this->validate($request,
            [
                'name' => 'required|string|alpha',
                'last_name' => 'required|string|alpha',
                'email' => 'required|email|unique:users',
            ],
            [
                'name.required' => 'Pole Imię jest wymagane',
                'name.alpha' => 'Pole zawiera niepoprawne znaki',
                'last_name.required' => 'Pole Nazwisko jest wymagane',
                'last_name.alpha' => 'Pole zawiera niepoprawne znaki',
                'email.required' => 'Pole Email jest wymagane',
                'email.email' => 'Niepoprawny email',
                'email.unique' => 'Email jest już zajęty',
            ]);

        try {
            $user = User::findorFail($id);
            $user->update($request->all());
            return response()->json(['data' => $user], 200);
        } catch (\Exception $e) {
            return response()->json(['message' => 'User Update Failed!'], 409);
        }
    }

I have tried adding $errors = ['name.required'...,] but the result was the same.

Upvotes: 2

Views: 540

Answers (1)

mrhn
mrhn

Reputation: 18926

First of all in line validation in controllers, is not at all an best approach, use FormRequest much cleaner and you get handling of errors for free. I once told lies to myself that the in line approach was quicker and no, it is not.

class UpdateUserRequest extends FormRequest {
    public function rules() {
        return [
            'name' => 'required|string|alpha',
            'last_name' => 'required|string|alpha',
            'email' => 'required|email|unique:users',
            ];
    }

    public function messages() {
        return [
            'name.required' => 'Pole Imię jest wymagane',
            'name.alpha' => 'Pole zawiera niepoprawne znaki',
            'last_name.required' => 'Pole Nazwisko jest wymagane',
            'last_name.alpha' => 'Pole zawiera niepoprawne znaki',
            'email.required' => 'Pole Email jest wymagane',
            'email.email' => 'Niepoprawny email',
            'email.unique' => 'Email jest już zajęty',
         ];
    }
}

Transforming your validation exception should be done in Exceptions/Handler.php, this will make all exceptions transform properly, removing clunky logic from multiple controllers.

public function render($request, \Throwable $exception)
{
    if ($request->expectsJson() && $exception instanceof ValidationException) {
        return response()->json([
            'errors' => $exception->errors(),
        ], Response::HTTP_UNPROCESSABLE_ENTITY);
    }

    ...
}

Check if API request or avoid this transformation with $request->expectsJson(), else simply transforming the result and we can make your controller method as simple as.

public function update(UpdateUserRequest $request, $id)
{
   $user = User::findorFail($id);

    $user->update($request->all());

    return response()->json(['data' => $user], 200);
}

And catching all exceptions does nothing, let the Exceptions/Handler.php handle that as well. For bonus points use model binding for the user too. But i think this is a big enough transformation as is.

Upvotes: 2

Related Questions