I'm trying to send a datetime field in JSON.
Here my JSON:
"mydate": "2015-07-07T22:00:00.000Z"
Here the PHP/Doctrine declaration:
/**
* #var \DateTime
*
* #ORM\Column(name="mydate", type="datetime")
*/
private $mydate;
But when I send the JSON in POST method, I got that error:
{
"code": 500,
"message": "Notice: Array to string conversion"
}
After debugging, I found that the error occur when my REST API Bundle (LemonRestBundle) calls the dezerialize() JMS method.
I just don't know why JMS can't deserialize my date to a PHP \DateTime... (if this is the problem...)
I've also tried this format:
"mydate": {
"lastErrors": {
"warning_count":0,
"warnings":[],
"error_count":0,
"errors":[]
},
"timezone": {
"name":"Europe\/Warsaw",
"location": {
"country_code":"PL",
"latitude":52.25,
"longitude":21,
"comments":""
}
},
"offset":7200,
"timestamp":1399413600
}
And thing like that:
"mydate": "2015/07/12"
Can someone help me on this ? Thanks! ;)
Related
I have a param in my API:
/** -------- */
#[ORM\JoinColumn(nullable: false)]
#[Groups([Group::CLIENT])]
#[Assert\NotBlank(message: "test not blank message")]
private ?Client $client = null;
/** -------------- */
When I call API without 'client' param I get correct answer:
{
"type": "https://tools.ietf.org/html/rfc2616#section-10",
"title": "An error occurred",
"detail": "client: test not blank message",
"violations": [
{
"propertyPath": "client",
"message": "test not blank message",
"code": "c1051bb4-d103-4f74-8988-acbcafc7fdc3"
}
]
}
But I need to check empty values as well and in this case I get Invalid IRI error.
Request:
{
...
"client": "",
...
}
Response:
{
"type": "https://tools.ietf.org/html/rfc2616#section-10",
"title": "An error occurred",
"detail": "Invalid IRI \"\".",
}
Is it possible to check type of requested param for embedded items in annotations? It works for not embedded items (error returns: the type of attribute must be ). But what about embedded.
I tried use Assert\Type + Assert\Valid but it does not work.
I'm using zircote/swagger-php to generated API documentation based on OpenApi annotations that I have added to existing code.
For the most part it's working fine, but I've noticed one strange bit. I have a method, indexAction(), that is supposed to return a list of items:
/**
* #OA\Get(
* path="\location",
* description="Retrieves a list of locations for the current organisation",
* method="indexAction",
* #OA\Response(
* response="200",
* description="List of locations",
* #OA\JsonContent(
* type="array",
* #OA\Items(ref="#/components/schemas/Location")
* ),
* #OA\XmlContent(
* type="array",
* #OA\Items(ref="#/components/schemas/Location")
* )
* )
* )
*/
public function indexAction()
{
After compiling the documentation json file, I open it and this action is listed as follows:
"paths": {
"\\location": {
"get": {
"summary": "The index action handles index/list requests; it should respond with a\nlist of the requested resources.",
"description": "Retrieves a list of locations for the current organisation",
"operationId": "2b36ea7d6a6e350fd6c7564bc908a25b",
"responses": {
"200": {
"description": "List of locations",
"content": {
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Location"
}
}
},
"application/xml": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/Location"
}
}
}
}
}
}
}
},
For some reason the "path" is listed as \\location instead of, as I expect, \location - does anyone know why this is happening? I hope this is enough, if more code is required I can supply it.
\\ is just an escaped version of the \ character in JSON strings. That is, the actual value of the "\\location" string is \location.
However, URL paths use / forward slashes, and OpenAPI also requires that paths start with /. So you need to replace
path="\location",
with
path="/location",
I am trying to use Symfony's Serializer to deserialize a Json to my entity "DossierDTO".
class DossierDTO
{
#[Groups(['test'])]
public string $idActeurCreateur;
#[Groups(['test'])]
public string $idDossierVise;
#[Groups(['test'])]
public string $idProjet;
public ArrayCollection $personnes;
public ArrayCollection $terrains;
.
.
.
more fields
I would like to deserialize only the fields tagged with the #[Groups(['test'])] annotations.
Here is my call to fetch the json object and my attempt to deserialize it:
/**
* Make a request to API
* #param string $method: request method (POST, GET...)
* #param string $suffix: URI suffix (/example)
* #param array $body: request body
* #throws Exception
* #return ResponseInterface
*/
public function myRequest(string $method, string $suffix, ?array $body): ResponseInterface
{
$jsonContent = is_null($body) ? json_encode(new stdClass) : $this->serializer->serialize($body, 'json');
try {
$response = $this->client->request($method, $this->infos["uri"] . $suffix, [
'headers' => $this->infos["headers"],
'body' => $jsonContent
]);
} catch (Exception $e) {
$this->logger->error($e->getMessage());
}
$dossier = $this->serializer->deserialize($response->getContent(), DossierDTO::class, 'json', ["groups" => "test"]);
dd($dossier, $response->getContent());
}
And this is what my dump shows:
So basically, I don't get the fields that I would like to, even when I remove the "#[Groups(['test'])]" the result is the same.
It always shows me the two ArrayCollection fields (empty) and only these...
I'm working with Symfony 5.2.9
From your screenshot I can see that response JSON has nested object, keyed by "projet". Looks like you are mapping incorrect structure. Try this:
$this->serializer->deserialize($response->getContent()['projet'], DossierDTO::class, 'json', ["groups" => "test"]);
I'm new to the API Platform and trying to get a json data attribute to persist to MySQL as a json object. I've looked over the API Platform documentation and googled for an answer, but didn't find anything that answers this.
My setup:
MySQL column is defined as:
`document` json DEFAULT NULL
I've defined a "MyEntity" PHP object and the json attribute is described as follows:
/**
* #var json
*
* #ORM\Column(type="json")
*/
private $document;
/**
* Get document.
*
* #return json
*/
public function getDocument()
{
return $this->document;
}
/**
* Set document.
*
* #param json $document
*
* #return MyEntity
*/
public function setDocument($document)
{
$this->document = $document;
return $this;
}
Now when up that URL that shows the default interface for MyEntity and execute a POST to create it using this json-ld (simplifying to leave out other columns):
{
"document": "{"test": "value"}"
}
I get a 400 Bad Request Error
{
"#context": "/contexts/Error",
"#type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Syntax error",
"trace": [
{
"namespace": "",
"short_class": "",
"class": "",
"type": "",
"function": "",
"file": "/Library/WebServer/Documents/test/vendor/symfony/symfony/src/Symfony/Component/Serializer/Encoder/JsonDecode.php",
"line": 78,
"args": []
},
...
I escaped the double quotes (which seems strange to me that it you would need to do this since it is a json itself that is describing another json object) like this:
{
"document": "{\"test\": \"value\"}"
}
and execute a POST again:
I get a 400 Bad Request Error with a different internal error:
{
"#context": "/contexts/Error",
"#type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Could not denormalize object of type AppBundle\\Entity\\json, no supporting normalizer found.",
"trace": [
{
"namespace": "",
"short_class": "",
"class": "",
"type": "",
"function": "",
"file": "/Library/WebServer/Documents/test/vendor/symfony/symfony/src/Symfony/Component/Serializer/Serializer.php",
"line": 295,
"args": []
},
...
So it look like API Platform doesn't recognize the JSON data type and is expecting a custom entity for it...doesn't seem right to me.
I've also looked at types for doctrine, which in my understanding, API Platform uses and found this info:
Some vendors have a native JSON type and Doctrine will use it if
possible and otherwise silently fall back to the vendor’s text type to
ensure the most efficient storage requirements. If the vendor does not
have a native JSON type, this type requires an SQL column comment hint
so that it can be reverse engineered from the database. Doctrine
cannot map back this type properly on vendors not supporting column
comments and will fall back to text type instead.
But since MySQL does support a JSON data type, I thought this would just work, but apparently not. Any help on how API Platform works with a JSON data type using MYSQL would be much appreciated.
You are getting this error because of your PHPdoc type hints. Api-platform uses PHPdoc metadata during normalization.
There is no such things as "json" data type in PHP, so it will look for a class in the same namespace.
From Doctrine documentation:
Values retrieved from the database are always converted to PHP’s array or null types using PHP’s json_decode() function.
So you should change your PHPDoc typehint to array
/**
* #var array
*
* #ORM\Column(type="json")
*/
private $document;
/**
* Get document.
*
* #return array
*/
public function getDocument()
{
return $this->document;
}
/**
* Set document.
*
* #param array $document
*
* #return MyEntity
*/
public function setDocument($document)
{
$this->document = $document;
return $this;
}
Hi Restler/Swagger friends,
I'm facing a problem when i trying to post a url (ex. /home/ahmad/) as follow:
{
"error": {
"code": 400,
"message": "Bad Request: `url` is required but missing."
},
"debug": {
"source": "Validator.php:26 at validate stage",
"stages": {
"success": [
"get",
"route",
"negotiate"
],
"failure": [
"validate",
"message"
]
}
}
}
my code for test is:
/**
* POST url
*
* #param string $url {#from url} url for test
*
* #return string
*/
function post_url($url) {
return $url;
}
I tried debugging the problem and discovered that url value is received as NULL before the Validator is applied
How i can solve such this problem?
I can see few problems with your approach
First, if you want to map a parameter to url you have to use {#from path} not {#from url}
Then if your variable is going to contain slashes they should ideally be mapped to query string or body as the slashes in the url path will be understood as many parameters by Restler
If you must accept it part of the url, you can use the wildcard routing as shown below
/**
* POST url
*
* #return string
*
* #url POST url/*
*/
function postUrl() {
return implode(',', func_get_args());
}