Links
📦

Request Body/Data

When sending HTTP requests, a common requirement is to attach a payload/body to POST, PUT, or PATCH requests, like JSON, XML or multipart data. Saloon makes this easy for you with built-in body traits.

Getting Started

To get started, you will need to add the HasBody interface to your request. This interface is required as it tells Saloon to look for a body() method supplied by one of the body traits. Without this interface, Saloon will not send any request body to the HTTP client. Also make sure to change your method to POST, PUT or PATCH depending on the requirements of the API.
<?php
use Saloon\Http\Request;
use Saloon\Contracts\Body\HasBody;
class CreateServerRequest extends Request implements HasBody
{
protected Method $method = Method::POST;
}
Next, you will need to add a trait to provide an implementation for the missing body() method. Saloon has a trait for all the common types of request bodies.
  • HasJsonBody - Sending JSON requests (application/json)
  • HasFormBody - Sending application/x-www-form-urlencoded requests
  • HasMultipartBody - Sending multipart/form-data requests
  • HasXmlBody - Sending application/xml requests
  • HasBody - Sending plain string body, you must specify the content-type.

HasJsonBody or HasFormBody

These two traits allow you to interact with the request body the same way, but each applies different strategies to encode the data and apply a different Content-Type header.

Adding Traits

HasJsonBody
HasFormBody
<?php
use Saloon\Http\Request;
use Saloon\Contracts\Body\HasBody;
use Saloon\Traits\Body\HasJsonBody;
class CreateServerRequest extends Request implements HasBody
{
use HasJsonBody;
}
<?php
use Saloon\Http\Request;
use Saloon\Contracts\Body\HasBody;
use Saloon\Traits\Body\HasFormBody;
class CreateServerRequest extends Request implements HasBody
{
use HasFormBody;
}

Interacting with the body() method

Once you have added one of the traits, you can access the body() method on your request. When using either the HasJsonBody or HasFormBody traits, you will have methods to add, remove, merge, set and retrieve all the properties in the data.
<?php
$request = new CreateServerRequest;
$request->body()->add('ubuntu_version', '22.04');
$request->body()->merge([
'type' => 'app',
'provider' => 'ocean2',
]);
$body = $request->body()->all();
// array: [
// 'ubuntu_version' => '22.04',
// 'type' => 'app',
// 'provider' => 'ocean2',
// ]

Available Methods

  • add(string $key, mixed $value)
  • remove(string $key)
  • merge(…$values)
  • set(array $value)
  • all(): array
  • isEmpty(): bool
  • isNotEmpty(): bool

Multipart Body

Saloon has also made it easier to send multipart form requests for attaching files. Once you have added the HasBody interface, add the HasMultipartBody trait. Next, you can use the available methods below to add/remove/get and set the multipart body. You may use the MultipartValue object if you want to define default multipart bodies to send.
Default Multipart Body Example
Adding Multipart File Example
<?php
use Saloon\Http\Request;
use Saloon\Contracts\Body\HasBody;
use Saloon\Traits\Body\HasMultipartBody;
class CreateServerRequest extends Request implements HasBody
{
use HasMultipartBody;
protected function defaultBody(): array
{
return [
new MultipartValue(name: 'logo', value: 'image-contents'),
new MultipartValue(name: 'logo', value: StreamObject),
new MultipartValue(name: 'logo', value: 'image-contents', filename: 'logo.png', headers: [...]),
];
}
}
<?php
$request = new CreateServerRequest;
$request->body()->add(
name: 'logo',
contents: 'your-file-contents-or-stream',
filename: 'logo.png',
headers: [
// Optional custom headers
]
);
// You may also get a multipart value by name.
$request->body()->get('logo'); // MultipartValue class
The contents of the MultipartValue class can be either the raw-text contents of the file or a PHP stream/resource.

Available Methods

  • add(string $key, mixed $value)
  • remove(string $key)
  • merge(…$values)
  • set(array $value)
  • all(): array
  • isEmpty(): bool
  • isNotEmpty(): bool

HasXmlBody or HasBody

These two traits do not encode the body. The HasXmlBody trait will apply the application/xml Content-Type header but the HasBody trait has been designed to be available for just sending raw string text with your Content-Type.

Adding Traits

HasXmlBody
HasBody
<?php
use Saloon\Http\Request;
use Saloon\Traits\Body\HasXmlBody;
use Saloon\Contracts\Body\HasBody;
class CreateServerRequest extends Request implements HasBody
{
use HasXmlBody;
}
<?php
use Saloon\Http\Request;
use Saloon\Traits\Body\HasBody;
use Saloon\Contracts\Body\HasBody as HasBodyContract;
class CreateServerRequest extends Request implements HasBodyContract
{
use HasBody;
}

Interacting with the body() method

Once you have added one of the traits, you can access the body() method on your request. When using either the HasXmlBody or HasBody traits, you will have basic methods to set and retrieve the plain string body.
<?php
$request = new CreateServerRequest;
$request->body()->set('plain-text-response-body');
$body = $request->body()->all();
// string: 'plain-text-response-body'

Available methods

  • set(?string $body)
  • all(): ?string
  • isEmpty(): bool
  • isNotEmpty(): bool

Default Body

Managing the body on the fly to requests is handy, but Saloon is all about standardising and re-using requests. You can also extend a defaultBody() method on the request to provide data; you could then accept constructor arguments for the request body. You may even want to accept a DTO through the constructor properties.
HasJsonBody, HasFormBody, HasMultipartBody
HasXmlBody, HasBody
<?php
use Saloon\Http\Request;
use Saloon\Contracts\Body\HasBody;
use Saloon\Traits\Body\HasJsonBody;
class CreateServerRequest extends Request implements HasBody
{
use HasJsonBody;
public function __construct(
protected string $ubuntuVersion,
protected string $type,
protected string $provider
){}
protected function defaultBody(): array
{
return [
'ubuntu_version' => $this->ubuntuVersion,
'type' => $this->type,
'provider' => $this->provider,
];
}
}
<?php
use Saloon\Http\Request;
use Saloon\Contracts\Body\HasBody;
use Saloon\Traits\Body\HasBody;
class CreateServerRequest extends Request implements HasBody
{
use HasBody;
public function __construct(
protected string $ubuntuVersion,
protected string $type,
protected string $provider
){}
protected function defaultBody(): string
{
return 'Default Raw Body';
}
}
Depending on the type of body you add, the defaultBodymethod will expect an array or string.

Connector Body

You may also use the HasBody and a body trait on your connector. When you have a connector with a body trait and a request, Saloon will prefer the request’s body type over the connector’s. Additionally, if you are using the HasJsonBody, HasFormBody, or HasMultipartBody traits on both, the arrays will be merged.
The same method is applied for adding body to a connector, add the interface and a body trait. You may also extend the defaultBody method.
<?php
use Saloon\Http\Connector;
use Saloon\Contracts\Body\HasBody;
use Saloon\Traits\Body\HasJsonBody;
class ForgeConnector extends Connector implements HasBody
{
use HasJsonBody;
protected function defaultBody(): array
{
return [
'name' => 'Sam',
];
}
}

Custom Request Body

While Saloon has covered most of the body types required for day-to-day integrations, you don't have to use one of the traits. You can build your own "BodyRepository" classes and use them in the body() method on your connector or request. Just make sure to add the HasBody interface as explained above.
<?php
use Saloon\Http\Request;
use Saloon\Contracts\Body\HasBody;
use Saloon\Contracts\Body\BodyRepository;
class CreateServerRequest extends Request implements HasBody
{
//
public function body(): BodyRepository
{
return new CustomBodyRepository();
}
}