scramble icon indicating copy to clipboard operation
scramble copied to clipboard

Wrong Attribute Margining on Response Example

Open kalimulhaq opened this issue 1 year ago • 2 comments

I have a scenario where I have a BaseResource that holds some common fields which are part of every model, and I want these to be included in every API resource that extends this base resource. See the following example code:

<?php

namespace App\Http\Resources;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\JsonResource;

class BaseResource extends JsonResource
{

    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return [
            'created_at' => $this->whenHas('created_at'),
            'updated_at' => $this->whenHas('updated_at'),
        ];
    }

}

<?php

namespace Domains\Organization\Http\Resources;

use App\Http\Resources\BaseResource;
use Illuminate\Http\Request;

class DivisionResource extends BaseResource
{

    /**
     * Transform the resource into an array.
     *
     * @return array<string, mixed>
     */
    public function toArray(Request $request): array
    {
        return array(
            'id' => $this->id,
            'name' => $this->whenHas('name'),
            ...parent::toArray($request),
        );

    }
}

The child resource class includes the fields from the parent resource class inside array methods. This is working perfectly, and the actual response includes those fields. However, the Response Example shows incorrect merging. See the screenshot.

image image

kalimulhaq avatar Aug 07 '24 10:08 kalimulhaq

Hey @kalimulhaq! Gotcha. Will fix. By the way, I can see the casing in the real API response is also different: while in the code base it is 'created_at', in the real response it is 'createdAt'. How that is implemented?

romalytvynenko avatar Aug 07 '24 13:08 romalytvynenko

@romalytvynenko

Thank you for your response. I have found a fix for now. The Scramble is working perfectly with the built-in merge function in the Resource class.

public function toArray(Request $request): array
{
    return [
        'id' => $this->id,
        'name' => $this->whenHas('name'),
        $this->merge(parent::toArray($request)),
    ];
}

Regarding the transformation of keys, we have a requirement to use camelCase for the API parameters while keeping the database column names in snake_case. To achieve this, we're using middleware to handle the transformation.

kalimulhaq avatar Aug 08 '24 08:08 kalimulhaq

fixed in #506

romalytvynenko avatar Sep 03 '24 07:09 romalytvynenko

@romalytvynenko I'm also using custom API resources and a middleware [to convert requests to snake_case and responses to camelCase] and this works fine, but I wish I could cast the metadata to camelcase as well.

{
  "data": [
    {
      "id": "string",
      "firstName": "string",
      "lastName": "string",
      "email": "string",
      "phone": "string",
      "avatar": "string",
      "idPassport": "string",
      "gender": "string",
      "roles": {},
      "emailVerifiedAt": "2019-08-24T14:15:22Z",
      "phoneVerifiedAt": "2019-08-24T14:15:22Z",
      "createdAt": "2019-08-24T14:15:22Z",
      "updatedAt": "2019-08-24T14:15:22Z"
    }
  ],
  "meta": {
    "current_page": 0,
    "from": 0,
    "last_page": 0,
    "links": [
      {
        "url": "string",
        "label": "string",
        "active": true
      }
    ],
    "path": "string",
    "per_page": 0,
    "to": 0,
    "total": 0
  },
  "links": {
    "first": "string",
    "last": "string",
    "prev": "string",
    "next": "string"
  }
}

maukoese avatar Nov 30 '24 11:11 maukoese