WackyStudio / build-an-api-with-laravel

Official Build an API with Laravel repository
122 stars 56 forks source link

Unique constraint is not working from jsonapi config file #37

Closed shamscorner closed 4 years ago

shamscorner commented 4 years ago

Hello, After reading your book, I am trying to implement my own API. I am having an issue here,

I want something like this in jsonapi.php config file for shops table, 'data.attributes.name' => 'required|unique:shops|string' but seems like it is not working. It is giving me 404 that means QueryException

I have also tried with this approach,

'data.attributes.name' => [
    'required',
    Illuminate\Validation\Rule::unique('shops'),
    'string'
]

But I got the serializing issue when running php artisan optimize command.

So how can I achieve this? All I want is a validation rule which will give me the error name already exists or something like that so that I can show in the frontend.

Thanks in advance.

ThomasNoergaard commented 4 years ago

Hello Shamim,

The QueryException you get when using the inline string approach, what does the exception tell you there?

shamscorner commented 4 years ago

Here is the test code and its output, Never mind the shop_types table, but the concept is same

Code

// create a shop type 
    $shopType = factory(ShopType::class)->create();

    // now create another shop type with the same shop type name 
    $r = $this->postJson('/api/v1/shop-types', [
        'data' => [
            'type' => 'shop-types',
            'attributes' => [
                'name' => $shopType->name,
                'description' => 'Lorem ipsum dolor emet',
                'image' => 'http://something.com/example.png'
            ]
        ]
    ],  [
        'accept' => 'application/vnd.api+json',
        'content-type' => 'application/vnd.api+json',
    ]);
    dd($r);

Output

Illuminate\Testing\TestResponse^ {#5214
  +baseResponse: Illuminate\Http\JsonResponse^ {#5537
    #data: "{"errors":[{"title":"Not Found Http Exception","details":"Resource not found"}]}"
    #callback: null
    #encodingOptions: 0
    +headers: Symfony\Component\HttpFoundation\ResponseHeaderBag^ {#5534
      #computedCacheControl: array:2 [
        "no-cache" => true
        "private" => true
      ]
      #cookies: []
      #headerNames: array:5 [
        "cache-control" => "Cache-Control"
        "date" => "Date"
        "content-type" => "content-type"
        "x-ratelimit-limit" => "X-RateLimit-Limit"
        "x-ratelimit-remaining" => "X-RateLimit-Remaining"
      ]
      #headers: array:5 [
        "cache-control" => array:1 [
          0 => "no-cache, private"
        ]
        "date" => array:1 [
          0 => "Wed, 08 Jul 2020 13:06:21 GMT"
        ]
        "content-type" => array:1 [
          0 => "application/vnd.api+json"
        ]
        "x-ratelimit-limit" => array:1 [
          0 => 60
        ]
        "x-ratelimit-remaining" => array:1 [
          0 => 59
        ]
      ]
      #cacheControl: []
    }
    #content: "{"errors":[{"title":"Not Found Http Exception","details":"Resource not found"}]}"
    #version: "1.1"
    #statusCode: 404
    #statusText: "Not Found"
    #charset: null
    +original: array:1 [
      "errors" => array:1 [
        0 => array:2 [
          "title" => "Not Found Http Exception"
          "details" => "Resource not found"
        ]
      ]
    ]
    +exception: Illuminate\Database\QueryException^ {#5529
      #sql: "select count(*) as aggregate from "shop_types" where "data"."attributes"."name" = ?"
      #bindings: array:1 [
        0 => "Ullam eos quod."
      ]
      #message: """
        SQLSTATE[42P01]: Undefined table: 7 ERROR:  missing FROM-clause entry for table "attributes"\n
        LINE 1: ...ect count(*) as aggregate from "shop_types" where "data"."at...\n
                                                                     ^ (SQL: select count(*) as aggregate from "shop_types" where "data"."attributes"."name" = Ullam eos quod.)
        """
      #code: "42P01"
      #file: "./vendor/laravel/framework/src/Illuminate/Database/Connection.php"
      #line: 671
      -previous: PDOException {#5071
        #message: """
          SQLSTATE[42P01]: Undefined table: 7 ERROR:  missing FROM-clause entry for table "attributes"\n
          LINE 1: ...ect count(*) as aggregate from "shop_types" where "data"."at...\n
                                                                       ^
          """
        #code: "42P01"
        #file: "./vendor/laravel/framework/src/Illuminate/Database/Connection.php"
        #line: 336
        +errorInfo: array:3 [
          0 => "42P01"
          1 => 7
          2 => """
            ERROR:  missing FROM-clause entry for table "attributes"\n
            LINE 1: ...ect count(*) as aggregate from "shop_types" where "data"."at...\n
                                                                         ^
            """
        ]
        trace: {
          ./vendor/laravel/framework/src/Illuminate/Database/Connection.php:336 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Connection.php:664 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Connection.php:631 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Connection.php:339 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2203 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2191 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2686 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2192 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2613 { …}
          ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2541 { …}
          ./vendor/laravel/framework/src/Illuminate/Validation/DatabasePresenceVerifier.php:55 { …}
          ./vendor/laravel/framework/src/Illuminate/Validation/Concerns/ValidatesAttributes.php:763 { …}
          ./vendor/laravel/framework/src/Illuminate/Validation/Validator.php:546 { …}
          ./vendor/laravel/framework/src/Illuminate/Validation/Validator.php:370 { …}
          ./vendor/laravel/framework/src/Illuminate/Validation/Validator.php:401 { …}
          ./vendor/laravel/framework/src/Illuminate/Validation/ValidatesWhenResolvedTrait.php:25 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Providers/FormRequestServiceProvider.php:30 { …}
          ./vendor/laravel/framework/src/Illuminate/Container/Container.php:1137 { …}
          ./vendor/laravel/framework/src/Illuminate/Container/Container.php:1101 { …}
          ./vendor/laravel/framework/src/Illuminate/Container/Container.php:1086 { …}
          ./vendor/laravel/framework/src/Illuminate/Container/Container.php:707 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Application.php:796 { …}
          ./vendor/laravel/framework/src/Illuminate/Container/Container.php:633 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Application.php:781 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php:79 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php:48 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php:28 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:41 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Route.php:239 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Route.php:196 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:685 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128 { …}
          ./app/Http/Middleware/EnsureCorrectAPIHeaders.php:33 {
            App\Http\Middleware\EnsureCorrectAPIHeaders->handle($request, Closure $next)^
            ›     // return the response with the correnct api spec content-type header
            ›     return $this->addCorrectContentType($next($request));
            › }
            arguments: {
              Illuminate\Http\Request {#5350 …}
            }
          }
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php:41 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php:59 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php:44 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:687 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:662 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:628 { …}
          ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:617 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:165 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php:63 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/fruitcake/laravel-cors/src/HandleCors.php:37 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/fideloper/proxy/src/TrustProxies.php:57 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
          ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:140 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:109 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:480 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:452 { …}
          ./vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:311 { …}
          ./tests/Feature/ShopType/ShopTypeTest.php:1025 { …}
          P\Tests\Feature\ShopType\ShopTypeTest->{closure}() {}
          ./vendor/pestphp/pest/src/Factories/TestCaseFactory.php:142 { …}
          P\Tests\Feature\ShopType\ShopTypeTest->Pest\Factories\{closure}() {}
          ./vendor/pestphp/pest/src/Concerns/TestCase.php:150 { …}
          ./vendor/pestphp/pest/src/Support/ExceptionTrace.php:28 { …}
          ./vendor/pestphp/pest/src/Concerns/TestCase.php:151 { …}
          ./vendor/pestphp/pest/src/Concerns/TestCase.php:139 { …}
          ./vendor/phpunit/phpunit/src/Framework/TestCase.php:1413 { …}
          ./vendor/phpunit/phpunit/src/Framework/TestCase.php:1030 { …}
          ./vendor/phpunit/phpunit/src/Framework/TestResult.php:692 { …}
          ./vendor/phpunit/phpunit/src/Framework/TestCase.php:771 { …}
          ./vendor/phpunit/phpunit/src/Framework/TestSuite.php:638 { …}
          ./vendor/phpunit/phpunit/src/Framework/TestSuite.php:638 { …}
          ./vendor/phpunit/phpunit/src/TextUI/TestRunner.php:657 { …}
          ./vendor/phpunit/phpunit/src/TextUI/Command.php:108 { …}
          ./vendor/pestphp/pest/src/Console/Command.php:128 { …}
          ./vendor/pestphp/pest/bin/pest:38 { …}
          ./vendor/pestphp/pest/bin/pest:39 { …}
        }
      }
      +errorInfo: array:3 [
        0 => "42P01"
        1 => 7
        2 => """
          ERROR:  missing FROM-clause entry for table "attributes"\n
          LINE 1: ...ect count(*) as aggregate from "shop_types" where "data"."at...\n
                                                                       ^
          """
      ]
      trace: {
        ./vendor/laravel/framework/src/Illuminate/Database/Connection.php:671 { …}
        ./vendor/laravel/framework/src/Illuminate/Database/Connection.php:631 { …}
        ./vendor/laravel/framework/src/Illuminate/Database/Connection.php:339 { …}
        ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2203 { …}
        ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2191 { …}
        ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2686 { …}
        ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2192 { …}
        ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2613 { …}
        ./vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2541 { …}
        ./vendor/laravel/framework/src/Illuminate/Validation/DatabasePresenceVerifier.php:55 { …}
        ./vendor/laravel/framework/src/Illuminate/Validation/Concerns/ValidatesAttributes.php:763 { …}
        ./vendor/laravel/framework/src/Illuminate/Validation/Validator.php:546 { …}
        ./vendor/laravel/framework/src/Illuminate/Validation/Validator.php:370 { …}
        ./vendor/laravel/framework/src/Illuminate/Validation/Validator.php:401 { …}
        ./vendor/laravel/framework/src/Illuminate/Validation/ValidatesWhenResolvedTrait.php:25 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Providers/FormRequestServiceProvider.php:30 { …}
        ./vendor/laravel/framework/src/Illuminate/Container/Container.php:1137 { …}
        ./vendor/laravel/framework/src/Illuminate/Container/Container.php:1101 { …}
        ./vendor/laravel/framework/src/Illuminate/Container/Container.php:1086 { …}
        ./vendor/laravel/framework/src/Illuminate/Container/Container.php:707 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Application.php:796 { …}
        ./vendor/laravel/framework/src/Illuminate/Container/Container.php:633 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Application.php:781 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php:79 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php:48 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/RouteDependencyResolverTrait.php:28 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:41 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Route.php:239 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Route.php:196 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:685 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128 { …}
        ./app/Http/Middleware/EnsureCorrectAPIHeaders.php:33 {
          App\Http\Middleware\EnsureCorrectAPIHeaders->handle($request, Closure $next)^
          ›     // return the response with the correnct api spec content-type header
          ›     return $this->addCorrectContentType($next($request));
          › }
          arguments: {
            Illuminate\Http\Request {#5350 …}
          }
        }
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php:41 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php:59 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php:44 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:687 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:662 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:628 { …}
        ./vendor/laravel/framework/src/Illuminate/Routing/Router.php:617 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:165 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:128 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php:21 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php:27 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php:63 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/fruitcake/laravel-cors/src/HandleCors.php:37 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/fideloper/proxy/src/TrustProxies.php:57 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:167 { …}
        ./vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php:103 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:140 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php:109 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:480 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:452 { …}
        ./vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MakesHttpRequests.php:311 { …}
        ./tests/Feature/ShopType/ShopTypeTest.php:1025 { …}
        P\Tests\Feature\ShopType\ShopTypeTest->{closure}() {}
        ./vendor/pestphp/pest/src/Factories/TestCaseFactory.php:142 { …}
        P\Tests\Feature\ShopType\ShopTypeTest->Pest\Factories\{closure}() {}
        ./vendor/pestphp/pest/src/Concerns/TestCase.php:150 { …}
        ./vendor/pestphp/pest/src/Support/ExceptionTrace.php:28 { …}
        ./vendor/pestphp/pest/src/Concerns/TestCase.php:151 { …}
        ./vendor/pestphp/pest/src/Concerns/TestCase.php:139 { …}
        ./vendor/phpunit/phpunit/src/Framework/TestCase.php:1413 { …}
        ./vendor/phpunit/phpunit/src/Framework/TestCase.php:1030 { …}
        ./vendor/phpunit/phpunit/src/Framework/TestResult.php:692 { …}
        ./vendor/phpunit/phpunit/src/Framework/TestCase.php:771 { …}
        ./vendor/phpunit/phpunit/src/Framework/TestSuite.php:638 { …}
        ./vendor/phpunit/phpunit/src/Framework/TestSuite.php:638 { …}
        ./vendor/phpunit/phpunit/src/TextUI/TestRunner.php:657 { …}
        ./vendor/phpunit/phpunit/src/TextUI/Command.php:108 { …}
        ./vendor/pestphp/pest/src/Console/Command.php:128 { …}
        ./vendor/pestphp/pest/bin/pest:38 { …}
        ./vendor/pestphp/pest/bin/pest:39 { …}
      }
    }
  }
  #streamedContent: null
}
ThomasNoergaard commented 4 years ago

So from the QueryException it's complaining about a undefined table. _select count(*) as aggregate from "shoptypes" where "data"."attributes"."name" = ?

The table here is shop_types, but the table you're giving in the validation rule is shops If you change the unique rule to use the shop_types table, it should be able to find the table

shamscorner commented 4 years ago

actually that was just for demo. Here is my config for shop types,

'shop-types' => [
            'allowedSorts' => [
                'name',
                'created_at',
                'updated_at'
            ],
            'validationRules' => [
                'create' => [
                    'data.attributes.name' => 'required|string|max:100|unique:shop_types',
                    'data.attributes.image' => 'string'
                ],
                'update' => [
                    'data.attributes.name' => 'sometimes|required|string|max:100',
                    'data.attributes.image' => 'string'
                ]
            ],
            'relationships' => []
        ]

Seems like there is some problem with unique Ok, let me try with this project after adding a unique rule to any of the configurations.

ThomasNoergaard commented 4 years ago

Do you still get the same QueryException?

shamscorner commented 4 years ago

I have tried with this test in the annas-bookstore repository. When I add the unique:books validation rule, it fails. If I remove that rule, it works fine.

it_can_create_an_book_from_a_resource_object

Code - jsonapi.php

'books' => [
            'allowedSorts' => [
                'title',
                'publication_year',
                'created_at',
                'updated_at',
            ],
            'allowedIncludes' => [
                'authors',
                'comments',
            ],
            'allowedFilters' => [],
            'validationRules' => [
                'create' => [
                    'data.attributes.title' => 'required|unique:books|string',
                    'data.attributes.description' => 'required|string',
                    'data.attributes.publication_year' => 'required|string',
                ],
                'update' => [
                    'data.attributes.title' => 'sometimes|required|string',
                    'data.attributes.description' => 'sometimes|required|string',
                    'data.attributes.publication_year' => 'sometimes|required|string',
                ]
            ],
            'relationships' => [
                [
                    'type' => 'authors',
                    'method' => 'authors',
                ],
                [
                    'type' => 'comments',
                    'method' => 'comments',
                ]
            ]
        ],

Code - BooksTest.php

$user = factory(User::class)->state('admin')->create();
        Passport::actingAs($user);

        $r = $this->postJson('/api/v1/books', [
            'data' => [
                'type' => 'books',
                'attributes' => [
                    'title' => 'Building an API with Laravel',
                    'description' => 'A book about API development',
                    'publication_year' => '2019',
                ]
            ]
        ], [
            'accept' => 'application/vnd.api+json',
            'content-type' => 'application/vnd.api+json',
        ]);
        dd($r);

Output:

 Illuminate\Foundation\Testing\TestResponse^ {#2642
  +baseResponse: Illuminate\Http\JsonResponse^ {#2939
    #data: "{"errors":[{"title":"Not Found Http Exception","details":"Resource not found"}]}"
    #callback: null
    #encodingOptions: 0
    +headers: Symfony\Component\HttpFoundation\ResponseHeaderBag^ {#2811
      #computedCacheControl: array:2 [
        "no-cache" => true
        "private" => true
      ]
      #cookies: []
      #headerNames: array:5 [
        "cache-control" => "Cache-Control"
        "date" => "Date"
        "content-type" => "content-type"
        "x-ratelimit-limit" => "X-RateLimit-Limit"
        "x-ratelimit-remaining" => "X-RateLimit-Remaining"
      ]
      #headers: array:5 [
        "cache-control" => array:1 [
          0 => "no-cache, private"
        ]
        "date" => array:1 [
          0 => "Wed, 08 Jul 2020 16:29:21 GMT"
        ]
        "content-type" => array:1 [
          0 => "application/vnd.api+json"
        ]
        "x-ratelimit-limit" => array:1 [
          0 => 60
        ]
        "x-ratelimit-remaining" => array:1 [
          0 => 59
        ]
      ]
      #cacheControl: []
    }
    #content: "{"errors":[{"title":"Not Found Http Exception","details":"Resource not found"}]}"
    #version: "1.1"
    #statusCode: 404
    #statusText: "Not Found"
    #charset: null
    +original: array:1 [
      "errors" => array:1 [
        0 => array:2 [
          "title" => "Not Found Http Exception"
          "details" => "Resource not found"
        ]
      ]
    ]
    +exception: Illuminate\Database\QueryException^ {#3081
      #sql: "select count(*) as aggregate from `books` where `data`.`attributes`.`title` = ?"
      #bindings: array:1 [
        0 => "Building an API with Laravel"
      ]
      #message: "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'data.attributes.title' in 'where clause' (SQL: select count(*) as aggregate from `books` where `data`.`attributes`.`title` = Building an API with Laravel)"
      #code: "42S22"
      #file: "C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php"
      #line: 664
      -previous: PDOException {#2937
        #message: "SQLSTATE[42S22]: Column not found: 1054 Unknown column 'data.attributes.title' in 'where clause'"
        #code: "42S22"
        #file: "C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php"
        #line: 326
        +errorInfo: array:3 [
          0 => "42S22"
          1 => 1054
          2 => "Unknown column 'data.attributes.title' in 'where clause'"
        ]
        trace: {
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php:326 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php:657 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php:624 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php:333 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2130 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2118 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2604 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2119 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2531 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2459 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\DatabasePresenceVerifier.php:55 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\Concerns\ValidatesAttributes.php:755 { …}     
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\Validator.php:398 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\Validator.php:277 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\Validator.php:302 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\ValidatesWhenResolvedTrait.php:25 { …}        
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Providers\FormRequestServiceProvider.php:30 { 
…}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:1084 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:1048 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:1033 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:687 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:615 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:767 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\RouteDependencyResolverTrait.php:79 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\RouteDependencyResolverTrait.php:46 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\RouteDependencyResolverTrait.php:27 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php:41 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Route.php:219 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Route.php:176 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:680 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:30 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authorize.php:45 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\app\Http\Middleware\EnsureCorrectAPIHeaders.php:30 {
            App\Http\Middleware\EnsureCorrectAPIHeaders->handle($request, Closure $next)^
            › \r
            ›     return $this->addCorrectContentType($next($request));\r
            › }\r
            arguments: {
              Illuminate\Http\Request {#2910 …}
            }
          }
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php:41 { …}        
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:43 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Middleware\ThrottleRequests.php:58 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:104 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:682 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:657 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:623 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:612 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:176 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:30 { …}
          C:\laragon\www\annas-bookstore\vendor\spatie\laravel-cors\src\Cors.php:28 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\fideloper\proxy\src\TrustProxies.php:57 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21 { …} 
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21 { …} 
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ValidatePostSize.php:27 { …}  
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php:62 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:104 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:151 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:116 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:375 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:347 { …}
          C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:210 { …}
          C:\laragon\www\annas-bookstore\tests\Feature\BooksTest.php:115 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestCase.php:1154 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestCase.php:842 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestResult.php:693 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestCase.php:796 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestSuite.php:746 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\TextUI\TestRunner.php:652 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\TextUI\Command.php:206 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\TextUI\Command.php:162 { …}
          C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\phpunit:61 { …}
        }
      }
      +errorInfo: array:3 [
        0 => "42S22"
        1 => 1054
        2 => "Unknown column 'data.attributes.title' in 'where clause'"
      ]
      trace: {
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php:664 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php:624 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Connection.php:333 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2130 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2118 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2604 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2119 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2531 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Database\Query\Builder.php:2459 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\DatabasePresenceVerifier.php:55 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\Concerns\ValidatesAttributes.php:755 { …}       
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\Validator.php:398 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\Validator.php:277 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\Validator.php:302 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Validation\ValidatesWhenResolvedTrait.php:25 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Providers\FormRequestServiceProvider.php:30 { …}        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:1084 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:1048 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:1033 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:687 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Container\Container.php:615 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Application.php:767 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\RouteDependencyResolverTrait.php:79 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\RouteDependencyResolverTrait.php:46 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\RouteDependencyResolverTrait.php:27 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php:41 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Route.php:219 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Route.php:176 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:680 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:30 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authorize.php:45 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\app\Http\Middleware\EnsureCorrectAPIHeaders.php:30 {
          App\Http\Middleware\EnsureCorrectAPIHeaders->handle($request, Closure $next)^
          › \r
          ›     return $this->addCorrectContentType($next($request));\r
          › }\r
          arguments: {
            Illuminate\Http\Request {#2910 …}
          }
        }
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Middleware\SubstituteBindings.php:41 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php:43 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Middleware\ThrottleRequests.php:58 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:104 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:682 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:657 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:623 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Router.php:612 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:176 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:30 { …}
        C:\laragon\www\annas-bookstore\vendor\spatie\laravel-cors\src\Cors.php:28 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\fideloper\proxy\src\TrustProxies.php:57 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21 { …}   
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\TransformsRequest.php:21 { …}   
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\ValidatePostSize.php:27 { …}    
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode.php:62 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:163 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Routing\Pipeline.php:53 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Pipeline\Pipeline.php:104 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:151 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php:116 { …}
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:375 { …} 
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:347 { …} 
        C:\laragon\www\annas-bookstore\vendor\laravel\framework\src\Illuminate\Foundation\Testing\Concerns\MakesHttpRequests.php:210 { …} 
        C:\laragon\www\annas-bookstore\tests\Feature\BooksTest.php:115 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestCase.php:1154 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestCase.php:842 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestResult.php:693 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestCase.php:796 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\Framework\TestSuite.php:746 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\TextUI\TestRunner.php:652 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\TextUI\Command.php:206 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\src\TextUI\Command.php:162 { …}
        C:\laragon\www\annas-bookstore\vendor\phpunit\phpunit\phpunit:61 { …}
      }
    }
  }
  #streamedContent: null
}
ThomasNoergaard commented 4 years ago

You have to specify which column it should validate against. which in this case would be the title column:

'data.attributes.title' => 'unique:books,title'

https://laravel.com/docs/7.x/validation#rule-unique https://laravel.com/docs/6.x/validation#rule-unique https://laravel.com/docs/5.8/validation#rule-unique

shamscorner commented 4 years ago

Awesome 😊 I thought the attribute name is optional. Thanks for your help. I am closing this thread.

ThomasNoergaard commented 4 years ago

You're welcome 😊