Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional Relationships in API Resource breaks relationship endpoints #130

Closed
helmroos opened this issue Oct 7, 2021 · 8 comments
Closed
Labels
bug Something isn't working
Milestone

Comments

@helmroos
Copy link
Contributor

helmroos commented Oct 7, 2021

Using Conditional Relationships in a API Resource class breaks the relationship self/related endpoints.

How to repro

  1. Have two related models, e.g. Users and Team
  2. In your UserSchema.php add the Team relationship like
use LaravelJsonApi\Eloquent\Fields\Relations\BelongsTo;

class UserSchema extends Schema
{
    public function fields(): array
    {
        return [
            ...
            BelongsTo::make('team'),
            ...
        ];
    }
}
  1. Setup routes, the following endpoints should now work:
  • /users/:id?include=team
  • /users/:id/team
  • /users/:id/relationships/team
  1. Now define a UserResource.php like so
use Illuminate\Http\Request;
use LaravelJsonApi\Core\Resources\JsonApiResource;

class UserResource extends JsonApiResource
{

    ...
    
    public function relationships($request): iterable
    {
        return [
            $this->relation('team')),
        ];
    }

}
  1. Try the three endpoints again, they should still work (3)
  2. Now make the relationships in the UserResource conditional:
return [
    $this->when(1===1, $this->relation('team')),
];
  1. Try the endpoints again, the relationship ones are now broken:
  • /users/:id?include=team => ✅ 200 OK
  • /users/:id/team => ☠️ 500 INTERNAL SERVER ERROR
  • /users/:id/relationships/team => ☠️500 INTERNAL SERVER ERROR

Stacktrace

[2021-10-07 10:15:21] local.ERROR: Call to undefined method LaravelJsonApi\Core\Resources\ConditionalField::fieldName() {"userId":"2f667dda-026e-4c8a-9acf-9e48523a2059","exception":"[object] (Error(code: 0): Call to undefined method LaravelJsonApi\\Core\\Resources\\ConditionalField::fieldName() at /var/www/html/vendor/laravel-json-api/core/src/Core/Resources/JsonApiResource.php:262)
[stacktrace]
#0 /var/www/html/vendor/laravel-json-api/core/src/Core/Responses/Internal/RelatedResourceResponse.php(108): LaravelJsonApi\\Core\\Resources\\JsonApiResource->relationship()
#1 /var/www/html/vendor/laravel-json-api/core/src/Core/Responses/Internal/RelatedResourceResponse.php(97): LaravelJsonApi\\Core\\Responses\\Internal\\RelatedResourceResponse->metaForRelationship()
#2 /var/www/html/vendor/laravel-json-api/core/src/Core/Responses/Internal/RelatedResourceResponse.php(81): LaravelJsonApi\\Core\\Responses\\Internal\\RelatedResourceResponse->allMeta()
#3 /var/www/html/vendor/laravel-json-api/core/src/Core/Responses/RelatedResponse.php(110): LaravelJsonApi\\Core\\Responses\\Internal\\RelatedResourceResponse->toResponse()
#4 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(776): LaravelJsonApi\\Core\\Responses\\RelatedResponse->toResponse()
#5 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(763): Illuminate\\Routing\\Router::toResponse()
#6 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(695): Illuminate\\Routing\\Router->prepareResponse()
#7 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}()
#8 /var/www/html/vendor/laravel-json-api/laravel/src/Http/Middleware/BootJsonApi.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#9 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): LaravelJsonApi\\Laravel\\Http\\Middleware\\BootJsonApi->handle()
#10 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#11 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle()
#12 /var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php(44): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#13 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Auth\\Middleware\\Authenticate->handle()
#14 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php(78): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#15 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken->handle()
#16 /var/www/html/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php(49): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#17 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\View\\Middleware\\ShareErrorsFromSession->handle()
#18 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(121): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#19 /var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php(64): Illuminate\\Session\\Middleware\\StartSession->handleStatefulRequest()
#20 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Session\\Middleware\\StartSession->handle()
#21 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php(37): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#22 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse->handle()
#23 /var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php(67): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#24 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Cookie\\Middleware\\EncryptCookies->handle()
#25 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#26 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(697): Illuminate\\Pipeline\\Pipeline->then()
#27 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(672): Illuminate\\Routing\\Router->runRouteWithinStack()
#28 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(636): Illuminate\\Routing\\Router->runRoute()
#29 /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php(625): Illuminate\\Routing\\Router->dispatchToRoute()
#30 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(166): Illuminate\\Routing\\Router->dispatch()
#31 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(128): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}()
#32 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#33 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#34 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle()
#35 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#36 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(40): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle()
#37 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle()
#38 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#39 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize->handle()
#40 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#41 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle()
#42 /var/www/html/vendor/fruitcake/laravel-cors/src/HandleCors.php(52): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#43 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fruitcake\\Cors\\HandleCors->handle()
#44 /var/www/html/vendor/fideloper/proxy/src/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#45 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(167): Fideloper\\Proxy\\TrustProxies->handle()
#46 /var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(103): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}()
#47 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(141): Illuminate\\Pipeline\\Pipeline->then()
#48 /var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(110): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter()
#49 /var/www/html/public/index.php(52): Illuminate\\Foundation\\Http\\Kernel->handle()
#50 /var/www/html/server.php(21): require_once('...')
#51 {main}
"} 

Response

500 INTERNAL SERVER ERROR

{
    "jsonapi": {
        "version": "1.0"
    },
    "errors": [
        {
            "detail": "Call to undefined method LaravelJsonApi\\Core\\Resources\\ConditionalField::fieldName()",
            "meta": {
                "exception": "Error",
                "file": "/var/www/html/vendor/laravel-json-api/core/src/Core/Resources/JsonApiResource.php",
                "line": 262,
                "trace": [
                    {
                        "file": "/var/www/html/vendor/laravel-json-api/core/src/Core/Responses/Internal/RelatedResourceResponse.php",
                        "line": 108,
                        "function": "relationship",
                        "class": "LaravelJsonApi\\Core\\Resources\\JsonApiResource",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel-json-api/core/src/Core/Responses/Internal/RelatedResourceResponse.php",
                        "line": 97,
                        "function": "metaForRelationship",
                        "class": "LaravelJsonApi\\Core\\Responses\\Internal\\RelatedResourceResponse",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel-json-api/core/src/Core/Responses/Internal/RelatedResourceResponse.php",
                        "line": 81,
                        "function": "allMeta",
                        "class": "LaravelJsonApi\\Core\\Responses\\Internal\\RelatedResourceResponse",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel-json-api/core/src/Core/Responses/RelatedResponse.php",
                        "line": 110,
                        "function": "toResponse",
                        "class": "LaravelJsonApi\\Core\\Responses\\Internal\\RelatedResourceResponse",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
                        "line": 776,
                        "function": "toResponse",
                        "class": "LaravelJsonApi\\Core\\Responses\\RelatedResponse",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
                        "line": 763,
                        "function": "toResponse",
                        "class": "Illuminate\\Routing\\Router",
                        "type": "::"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
                        "line": 695,
                        "function": "prepareResponse",
                        "class": "Illuminate\\Routing\\Router",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 128,
                        "function": "Illuminate\\Routing\\{closure}",
                        "class": "Illuminate\\Routing\\Router",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel-json-api/laravel/src/Http/Middleware/BootJsonApi.php",
                        "line": 103,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "LaravelJsonApi\\Laravel\\Http\\Middleware\\BootJsonApi",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php",
                        "line": 50,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Routing\\Middleware\\SubstituteBindings",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php",
                        "line": 44,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Auth\\Middleware\\Authenticate",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/VerifyCsrfToken.php",
                        "line": 78,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Foundation\\Http\\Middleware\\VerifyCsrfToken",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/View/Middleware/ShareErrorsFromSession.php",
                        "line": 49,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\View\\Middleware\\ShareErrorsFromSession",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php",
                        "line": 121,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Session/Middleware/StartSession.php",
                        "line": 64,
                        "function": "handleStatefulRequest",
                        "class": "Illuminate\\Session\\Middleware\\StartSession",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Session\\Middleware\\StartSession",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/AddQueuedCookiesToResponse.php",
                        "line": 37,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Cookie\\Middleware\\AddQueuedCookiesToResponse",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Cookie/Middleware/EncryptCookies.php",
                        "line": 67,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Cookie\\Middleware\\EncryptCookies",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 103,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
                        "line": 697,
                        "function": "then",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
                        "line": 672,
                        "function": "runRouteWithinStack",
                        "class": "Illuminate\\Routing\\Router",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
                        "line": 636,
                        "function": "runRoute",
                        "class": "Illuminate\\Routing\\Router",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Routing/Router.php",
                        "line": 625,
                        "function": "dispatchToRoute",
                        "class": "Illuminate\\Routing\\Router",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
                        "line": 166,
                        "function": "dispatch",
                        "class": "Illuminate\\Routing\\Router",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 128,
                        "function": "Illuminate\\Foundation\\Http\\{closure}",
                        "class": "Illuminate\\Foundation\\Http\\Kernel",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
                        "line": 21,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php",
                        "line": 31,
                        "function": "handle",
                        "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php",
                        "line": 21,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php",
                        "line": 40,
                        "function": "handle",
                        "class": "Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Foundation\\Http\\Middleware\\TrimStrings",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php",
                        "line": 27,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Foundation\\Http\\Middleware\\ValidatePostSize",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php",
                        "line": 86,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/fruitcake/laravel-cors/src/HandleCors.php",
                        "line": 52,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Fruitcake\\Cors\\HandleCors",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/fideloper/proxy/src/TrustProxies.php",
                        "line": 57,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 167,
                        "function": "handle",
                        "class": "Fideloper\\Proxy\\TrustProxies",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php",
                        "line": 103,
                        "function": "Illuminate\\Pipeline\\{closure}",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
                        "line": 141,
                        "function": "then",
                        "class": "Illuminate\\Pipeline\\Pipeline",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php",
                        "line": 110,
                        "function": "sendRequestThroughRouter",
                        "class": "Illuminate\\Foundation\\Http\\Kernel",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/public/index.php",
                        "line": 52,
                        "function": "handle",
                        "class": "Illuminate\\Foundation\\Http\\Kernel",
                        "type": "->"
                    },
                    {
                        "file": "/var/www/html/server.php",
                        "line": 21,
                        "function": "require_once"
                    }
                ]
            },
            "status": "500",
            "title": "Internal Server Error"
        }
    ]
}

Other details

I can repro both in PHPUnit and manually, using either a Web (Laravel Sanctum) or API (Laravel Passport) guard with the folllowing in composer.json:

  • "laravel-json-api/laravel": "^1.0"
  • "laravel-json-api/non-eloquent": "^1.0"
  • "laravel/framework": "^8.40"
  • "laravel/passport": "^10.1"
  • "laravel/sanctum": "^2.11"

php -v:

PHP 8.0.11 (cli) (built: Sep 23 2021 21:26:42) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.11, Copyright (c) Zend Technologies
    with Zend OPcache v8.0.11, Copyright (c), by Zend Technologies
    with Xdebug v3.0.4, Copyright (c) 2002-2021, by Derick Rethans
@lindyhopchris lindyhopchris added the bug Something isn't working label Oct 7, 2021
@lindyhopchris
Copy link
Contributor

Thanks for reporting.

@estuardoquan
Copy link

@helmroos any solution?

@lindyhopchris
Copy link
Contributor

There's probably no work around for this - it needs me to have time to implement a fix, or for someone else to submit a PR fixing it.

@estuardoquan
Copy link

estuardoquan commented Nov 9, 2021

@lindyhopchris so I noticed that within the relationship method in theJsonApiResource Class, conditional relationships are given as a ConditionalField object and not as Relation Object... Barely fiddling with the code because I don't understand sh*t of what is going on (pardon my french) I managed to pass all the test (relationship endpoints) by re-writing the relationship method to...

/**
* Get a resource relation by name.
*
* @param string $name
* @return JsonApiRelation
*/
public function relationship(string $name): JsonApiRelation
{
   /** @var JsonApiRelation $relation */
   foreach ($this->relationships(null) as $relation) {
      $relation instanceof JsonApiRelation ?: $relation = ($relation)(); // Invoke (I think) ConditionalField class to return value
      if ($relation->fieldName() === $name) {
           return $relation;
      }
   }

    throw new LogicException(sprintf(
        'Unexpected relationship %s on resource %s.',
        $name,
        $this->type()
   ));
}

This works but I do not understand neither why, nor how... I would've thought that instead of calling ($relation)() I could've just called $relation->get() but this throws a serialization error... does this work around seem logical?

@lindyhopchris
Copy link
Contributor

I think it should actually be checking whether $relation is conditional, and if its - resolve it. I think this is probably one I'm going to have to look at.

@estuardoquan
Copy link

how would one "resolve it"?

@estuardoquan
Copy link

leaving a note that my solution of

$relation instanceof JsonApiRelation ?: $relation = ($relation)();

only works with when and not mergeWhen, for ConditionalFields is not callable, as is ConditionalField...

@lindyhopchris lindyhopchris added this to the 1.x milestone Jan 2, 2022
@lindyhopchris
Copy link
Contributor

Will be in the 1.1 release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants