I am using Symfony 5.4 with PHP 7.4. I use MongoDB too. I want to use the Nelmio Api Doc Bundle to document the routes. Partly it works, but I have a problem when I have an array in my entity.
I have an entity "Order" which looks like this:
<?php
namespace App\Entity;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* @MongoDB\Document
*/
class Order
{
/**
* @MongoDB\Id
*/
protected $id;
/**
* @MongoDB\Field(type="string")
*/
protected $orderNumber;
/**
* @MongoDB\Field(type="string")
*/
protected $firstname;
/**
* @MongoDB\Field(type="string")
*/
protected $lastname;
/**
* @MongoDB\Field(type="collection")
*
*/
protected $address;
/**
* @MongoDB\Field(type="string")
*/
protected $orderFile;
/**
* Get the value of id.
*/
public function getId(): string
{
return $this->id;
}
/**
* Get the value of firstname.
*/
public function getFirstname(): string
{
return $this->firstname;
}
/**
* Set the value of firstname.
*/
public function setFirstname(string $firstname): void
{
$this->firstname = $firstname;
}
/**
* Get the value of lastname.
*/
public function getLastname(): string
{
return $this->lastname;
}
/**
* Set the value of lastname.
*/
public function setLastname(string $lastname): void
{
$this->lastname = $lastname;
}
/**
* Get the value of address.
*/
public function getAddress(): array
{
return $this->address;
}
/**
* Set the value of address.
*/
public function setAddress(array $address): void
{
$this->address = $address;
}
}
I have a controller with my route and annotations for the bundle or doc. It looks like this:
Now as an error message I get the following:
<?php
namespace App\Controller\Api;
use App\Entity\Order;
use Doctrine\ODM\MongoDB\DocumentManager;
use Nelmio\ApiDocBundle\Annotation\Model;
use OpenApi\Annotations as OA;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
/**
* @Route("/api/orders")
*/
class OrderApiController extends AbstractController
{
/**
* Creates a new order.
*
* @Route("", methods={"POST"})
*
* @OA\Response(
* response=200,
* description="Creates a new order",
*
* @Model(type=Order::class)
* )
*
* @OA\RequestBody(
* required=true,
*
* @OA\MediaType(
* mediaType="application/json",
*
* @OA\Schema(
* type="object",
* required={"address"},
*
* @OA\Property(
* property="address",
* type="array",
*
* @OA\Items(type="object")
* ),
* )
* )
* )
*
* @OA\Tag(name="Order")
*/
public function create(DocumentManager $dm, Request $request): JsonResponse
{
// ... some code here
}
Now as an error message I get the following:
Property "App\Entity\Order::address" is an array, but its items type isn't specified. You can specify that by using the type string[]
for instance or @OA\Property(type="array", @OA\Items(type="string"))
.
Does anyone have any idea why I absolutely need to specify the type of the items and how to specify it correctly? Also as info.... the address array always contains two objects. It looks something like this:
[
{
"addresstype" : "delivery",
"company" : "Test",
"firstname" : "",
"lastname" : "",
"address1" : "",
"address2" : "",
"zip" : "",
"city" : "Musterstadt",
"country" : "DE"
},
{
"addresstype" : "invoice",
"company" : "Test",
"firstname" : "",
"lastname" : "",
"address1" : "",
"address2" : "",
"zip" : "",
"city" : "Musterstadt",
"country" : "DE"
}
]
I have tried different ways to define the items. For the most part, I have followed this documentation:
https://symfony.com/bundles/NelmioApiDocBundle/current/index.html#use-models
I also searched with Google and asked Chat GPT. I can't find a workable solution.
If I use as a test an entity only with fields that expect a string, the bundle runs as well. Only this special case I don't understand.
First, thank you @Đuro Mandinić! I will try your solution in the future too. But for now I was able to "fix" my problem like this.
In my order class I added an annotation for the items of address.
/**
* @MongoDB\Field(type="collection")
*
* @OA\Property(property="address", type="array", @OA\Items(type="object"))
*/
protected $address;
Hope this helps others too!
Have a nice day!