framework: [API Resource] Error 500 when query result is empty

  • Laravel Version: 5.5.22
  • PHP Version: 7.1
  • Database Driver & Version: MySQL 5.6

Description:

Api resource error when query result is null as follow in official document example.

    public function show($id)
    {
        return new UserResource(User::find($id));
    }

Assume that $id = 20 and there is no user with id = 20

Steps To Reproduce:

  1. return api resource with empty result in controller
  2. 500 server error occur

About this issue

  • Original URL
  • State: closed
  • Created 6 years ago
  • Comments: 15 (7 by maintainers)

Most upvoted comments

But you will still get error if return a transformation array instead of return parent::toArray($request);:

class User extends JsonResource
{
    /**
     * Transform the resource into an array.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
        ];
    }
}
public function show($id)
{
    return new UserResource(null);
}
{
  "message": "Trying to get property 'id' of non-object",
  "exception": "ErrorException",
  "file": "vendor\\laravel\\framework\\src\\Illuminate\\Http\\Resources\\DelegatesToResource.php",
  "line": 120,
  "trace": [
    ...
  ]
}

The responsibility of a resource class is to transform your model into JSON. That obviously isn’t gonna work when you pass null. You better check for existence of the model in your controller, or use findOrFail to automatically trigger a 404.

But this isn’t the place for code level support, this is for reporting bugs and issues of the framework.

@GuidoHendriks OK, then the official document should not use something like ::find($id). The doc made me think that it doesn’t require to check for null before using it, the expectation is something like null value in data key.

I just overrided the Resource@resolve() method, to handle these kinds of cases by adding this to the start of the method.

public function resolve($request = null)
{
        if($this->resource == null){
            return null;
         ....
}