framework: In API resource, ConditionallyLoadsAttributes::attributes() improperly converts Carbon objects to strings

  • Laravel Version: 5.7.3
  • PHP Version: 7.2.10

Description:

When using $this->attributes() in an API resource, it calls $this->resource->toArray() which converts Carbon objects to strings using the model’s serializeDate method instead of Carbon’s native serializeJson method. This is not the expected behaviour. The date serialization format (e.g. for MySQL) is not necessarily what one would want to use for an API response (ISO8601).

Example Resource:

public function toArray($request)
{
    return [
        $this->attributes([
            'created_at',
        ]),
    ];
}

This returns {"created_at":"2018-10-02 05:59:58"} by default, which doesn’t include the timezone so is not suitable for an API response.

public function toArray($request)
{
    return [
        'created_at' => $this->created_at,
    ];
}

This returns the correct response: {"created_at":"2018-10-02T05:59:58Z"}.

The work-around is easy, but it took me some time debugging to figure out what was going on. attributes is convenient for keeping the resource code clean and not repetitive. I believe it should return Carbon objects, so that their underlying serializeJson methods can be called instead of making assumptions about the desired format.

About this issue

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

Most upvoted comments

I’m re-opening this to give this some more thought at a later time. I feel like we should get to the bottom of this but currently don’t have the time to check into it.