Example of Form requests in tighten/novapackages

File app/Http/Requests/PackageFormRequest.php (link to Github)
use App\Collaborator;
use App\Package;
use App\Screenshot;
use App\Tag;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Str;
use Illuminate\Validation\ValidationException;

class PackageFormRequest extends FormRequest
{
    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        return [
            'author_id' => 'required|exists:collaborators,id',
            'contributors' => 'array',
            'tags' => 'array',
            'tags-new' => 'array',
            'name' => 'required',
            'packagist_namespace' => 'required',
            'packagist_name' => [
                'required',
                function ($attribute, $value, $fail) {
                    $composerName = $this->getComposerName();

                    if (! $this->packageStringUnique(request('any_package')->id ?? null)) {
                        $fail("The package {$composerName} has already been submitted.");
                    }
                },
            ],
            'url' => 'required|url',
            'abstract' => 'required|max:190',
            'screenshots' => [
                'array',
                function ($attribute, $value, $fail) {
                    $value = (is_array($value)) ? $value : [];

                    if (count($value) > 20) {
                        $deleteCount = count($value) - 20;
                        $fail("You may only upload 20 {$attribute}. Please delete {$deleteCount} ".Str::plural('screenshot', $deleteCount));
                    }
                },
            ],
        ];
    }

    public function getComposerName()
    {
        return request('packagist_namespace').'/'.request('packagist_name');
    }

    protected function failedValidation(Validator $validator)
    {
        throw new ValidationException($validator, $this->failedValidationResponse($validator));
    }

    private function failedValidationResponse($validator)
    {
        $collaborators = Collaborator::inRequest(request())->get();

        $newTags = collect(request('tags-new', []))->map(function ($item) {
            return ['name' => $item];
        });

        return redirect()
                ->back()
                ->withErrors($validator)
                ->withInput(array_merge(request()->all(), [
                    'selectedAuthor' => $collaborators->where('id', request('author_id', null))->first(),
                    'selectedCollaborators' => $collaborators->whereIn('id', request('contributors', []))->values(),
                    'selectedTags' => Tag::whereIn('id', request('tags', []))->get()->toBase()->merge($newTags),
                    'screenshots' => Screenshot::forRequest(request('screenshots')),
                ]));
    }

    private function packageStringUnique($id = null)
    {
        $query = Package::where('composer_name', $this->getComposerName());

        if ($id) {
            $query->where('id', '!=', $id);
        }

        return $query->count() == 0;
    }
}

Additional resources on Form requests: