spatie / laravel-query-builder

Easily build Eloquent queries from API requests
https://spatie.be/docs/laravel-query-builder
MIT License
4k stars 392 forks source link

Add the possibility to use the relation names on the allowedFields. #917

Closed carvemerson closed 7 months ago

carvemerson commented 7 months ago

Problem:

Package currently converts relation names to plural snake_case in fields parameters, causing inconsistencies when using singular relation names in API requests.

Suppose that I have the bellow model:

class Task extends Model
{
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

    public function userOwnerTestName(): BelongsTo
    {
        return $this->belongsTo(User::class, 'user_id');
    }
}

I would like to request the userOwnerTestName relationship, my first try was do this:

api/v1/tasks?include=userOwnerTestName&fields[userOwnerTestName]=id,email&fields[tasks]=user_id

and the response is:

 "data": [
    {
        "user_id": "9b055f1c-caae-40ca-aa4a-79a5a42a9dd3",
        "userOwnerTestName": {
            "id": "9b055f1c-caae-40ca-aa4a-79a5a42a9dd3",
            "name": "Mavis Erdman I",
            "email": "delilah.walker@example.com"
        }
    },
    {
        "user_id": "9b055f1c-caae-40ca-aa4a-79a5a42a9dd3",
        "userOwnerTestName": {
            "id": "9b055f1c-caae-40ca-aa4a-79a5a42a9dd3",
            "name": "Mavis Erdman I",
            "email": "delilah.walker@example.com"
        }
    },
]

But I was expecting:

 "data": [
    {
        "user_id": "9b055f1c-caae-40ca-aa4a-79a5a42a9dd3",
        "userOwnerTestName": {
            "id": "9b055f1c-caae-40ca-aa4a-79a5a42a9dd3",
            "email": "delilah.walker@example.com"
        }
    },
    {
        "user_id": "9b055f1c-caae-40ca-aa4a-79a5a42a9dd3",
        "userOwnerTestName": {
            "id": "9b055f1c-caae-40ca-aa4a-79a5a42a9dd3",
            "email": "delilah.walker@example.com"
        }
    },
]

If I change the request to:

api/v1/tasks?include=userOwnerTestName&fields[user_owner_test_names]=id,email&fields[tasks]=user_id

it works like a charm! But I need to convert the relationship name to plural and use the snake_case format.

Solution:

Introduce a configuration option to control relation name conversion:

Example Usage:

// Original behavior (plural snake_case):
api/tasks?include=userOwnerTestName&fields[user_owner_test_names]=id,name
// New behavior (preserves relation name):
api/tasks?include=userOwnerTestName&fields[userOwnerTestName]=id,name
AlexVanderbist commented 7 months ago

Thanks, LGTM! Glad to have one of the final todos in the package done 👍 I'll merge this, add a test for it and tag a new release.