3

Goal: Output a custom validation message when attempting to insert a duplicate database record via GraphQL mutation using Laravel Lighthouse.

I've got a unique key constraint being enforced on these multiple fields at the database layer via Laravel migration ($table->unique(['field_1','field_2','field_3'],'pivot_model_unique');), and it works, but this outputs an "Internal Server Error" upon a duplicate entry attempt, and that's no good. I want to make it clear to the client via custom error message why the request is denied.

My GraphQL schema:

type PivotModel {
  id: ID!
  field_1: ID!
  field_2: ID!
  field_3: ID!
}

type Mutation {
  createPivotModel(pivot_model: CreatePivotModelInput! @spread): PivotModel!
    @create
}

input CreatePivotModelInput @validator(class: "PivotModelInputValidator") {
  field_1: ID!
  field_2: ID!
  field_3: ID!
}

My custom Lighthouse Validator class:

<?php
declare(strict_types=1);

namespace App\GraphQL\Validators;

use Illuminate\Validation\Rule;
use Nuwave\Lighthouse\Validation\Validator;

class PivotModelInputValidator extends Validator
{
    /**
     * Return the validation rules.
     *
     * @return array<string, array<mixed>>
     */
    public function rules(): array
    {
        return [
            'field_1' => [
                'filled',
                'numeric',
                'integer',
                Rule::unique('pivot_model')->where(function ($query) {
                    return $query
                        ->where('field_1', $this->arg('field_1'))
                        ->where('field_2', $this->arg('field_2'))
                        ->where('field_3', $this->arg('field_3'));
                }),
            ],
            'field_2' => [
                'filled',
                'numeric',
                'integer',
            ],
            'field_3' => [
                'filled',
                'numeric',
                'integer',
            ],
        ];
    }

    /**
     * Return messages for validation errors.
     *
     * @return array
     */
    public function messages(): array
    {
        return [
            'field_1.unique' => 'duplicate_entry'
        ];
    }
}

My request:

mutation CreatePivotModel {
  createPivotModel(
    pivot_model: { field_1: 1, field_2: 100, field_3: 1000 }
  ) {
    field_1
    field_2
    field_3
  }
}

The response:

{
  "errors": [
    {
      "message": "Validation failed for the field [createPivotModel].",
      "extensions": {
        "validation": {
          "pivot_model.field_1": [
            "duplicate_entry"
          ]
        },
        "category": "validation"
      },
      ...
    }
  ]
}

This response is output when running that mutation operation regardless if the mutation's arguments are supplied with duplicate or unique data.

It doesn't seem to recognize the closure of where clauses in the Lighthouse Validator class to check the other fields, as though it's functionally equivalent to 'field_1' => 'unique:pivot_model'.

I've tried every answer in this thread and they don't seem to work.

user110857
  • 2,023
  • 1
  • 21
  • 33

0 Answers0