saloon icon indicating copy to clipboard operation
saloon copied to clipboard

Cannot Have Request with `headers`

Open davidhemphill opened this issue 1 year ago • 2 comments

Hi! I'm using Saloon to create an SDK for a project. I have a request class I would like to have this API:

namespace Project;

use Saloon\Contracts\Body\HasBody;
use Saloon\Enums\Method;
use Saloon\Http\Request;
use Saloon\Traits\Body\HasJsonBody;


class CreateRequest extends Request implements HasBody
{
    use HasJsonBody;

    protected Method $method = Method::POST;

    public function __construct(public string $name, public array $headers = [], public array $payload = [])
    {
    }

    public function resolveEndpoint(): string
    {
        return '/endpoint';
    }

    public function defaultBody(): array
    {
        return [
            'name' => $this->name,
            'headers' => $this->headers,
            'payload' => $this->payload,
        ];
    }
}
$connector = new ProjectConnector;

$request = CreateRequest::make(
    name: 'test',
    headers: ['foo', 'bar'],
    payload: ['boo' => 'baz'],
);

$response = $connector->send($request);

I'm not able to use this as it causes a type error since headers is already defined on Request via HasHeaders using a different type.

I would love to find a way around this since it makes most sense for my users to be able to use the header parameter name.

Thank you!

davidhemphill avatar Feb 22 '24 23:02 davidhemphill

Upon looking further, if I wanted to switch payload to be named body, I would run into this problem again.

I understand it's probably an esoteric problem due to my project's nature, but maybe not?

davidhemphill avatar Feb 22 '24 23:02 davidhemphill

Hey @davidhemphill I hope you are well!

I think you may just be a little unlucky in this scenario where you have run into property names that are already being used by Saloon behind the scenes. You would need to change the names of the properties in your constructor for it to work, Sadly. Sorry!

For headers you could have:

  • bodyHeaders
  • _headers? Although I don't like this one as much

Or you could use a DTO to pass in the fields?

public function __construct(public CreateRequestData $data)
{
}

public function defaultBody(): array
{
    return [
        'name' => $this->data->name,
        'headers' => $this->data->headers,
        'payload' => $this->data->payload,
    ];
}

With the DTO approach, you could have the same names!

Sammyjo20 avatar Feb 25 '24 15:02 Sammyjo20

Hey @davidhemphill I hope you're doing well. Did my last response help resolve the issue you were having?

Sammyjo20 avatar Mar 19 '24 23:03 Sammyjo20

Hi @Sammyjo20, I wound up resolving this by using a DTO. Thanks!

davidhemphill avatar Mar 20 '24 14:03 davidhemphill