Streetlamp supports object mapping with the help of the DataBindingObjectInterface
.
You can either use pre-existing data bindings which are currently limited to JSON, or alternatively create your own.
Again, as with most parts of Streetlamp, the data mapping has fully supported extensibility to fit your needs.
As JSON is the most commonly used format for data exchange, there's an included set of libraries to allow you to map data in both directions.
When defining a data binding in your route, you simply need to bind the input to that particular route.
Similarly, if you want to return an object you just need to set it as the data in the ResponseBuilder
.
#[JsonObject]
#[JsonIgnore]
#[JsonProperty(bool $required = true, ?string $alias = null)]
#[JsonArray(string $className, bool $required = true, ?string $alias = null)]
#[RouteController]
#[Path('/person')]
class Person
{
#[Method(HttpMethod::POST)]
#[Accepts(MediaType::APPLICATION_JSON)]
public function createPerson(
#[BodyParameter] PersonModel $personModel
): ResponseBuilder
{
return (new ResponseBuilder())
->setData($personModel)
->setHttpStatusCode(HttpStatusCode::HTTP_OK)
->setContentType(MediaType::APPLICATION_JSON);
}
}
#[JsonObject]
class PersonModel
{
#[JsonProperty(true)]
#[AlphabeticValidator]
private string $name;
#[JsonProperty]
private AgeModel $data;
public function __construct(
#[JsonProperty(true)]
#[JsonIgnore]
private string $email
) {}
}
As shown in the above example you can use the annotation JsonProperty
at both member and constructor levels.
curl --request POST \
--location 'http://localhost/person' \
--header 'Content-Type: application/json' \
--data-raw '{
"name": "test",
"email": "[email protected]",
"data": {
"age": 60
}
}'
In addition to mapping objects directly to variables, you can also map arrays of objects too.
This is done using the JsonArray
attribute which can be applied to input parameters and properties of a JsonObject
.
#[Method(HttpMethod::POST)]
#[Path('/array')]
public function mapJsonArray(
#[BodyParameter]
#[JsonArray(DataType::class)] array $dataTypes
): ResponseBuilder {
return (new ResponseBuilder())
->setData($dataTypes)
->setContentType(MediaType::APPLICATION_JSON)
->setHttpStatusCode(HttpStatusCode::HTTP_OK);
}
The JsonArray
object defined must be a JsonObject
and each object will apply the validation rules where applicable too.
#[JsonObject]
readonly class NestedDataType
{
public function __construct(
#[JsonArray(DataType::class, true)] public array $dataTypeArray,
#[JsonProperty(true)] public array $nativeArray
) {
}
}
Only one of either the JsonArray
or JsonProperty
can be applied to a property with the JsonArray
taking priority.