I am using nelmioapidocbundle in order to documents my Rest API built on the top of symfony-2.x.
I can't found the right annotation to use to show each Entity's property description on the return section (Please see bellow attached image).
My Entity :
/**
* Checkins
*
* #ORM\Table(name="CheckIns")
* #ORM\Entity(repositoryClass="Project1\ApiBundle\Entity\CheckinsRepository")
*
* #ExclusionPolicy("none")
*/
class Checkins
{
/**
* #var integer
*
* #ORM\Column(name="id", type="bigint", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*
* #Groups({"checkin"})
* #
*/
private $id;
My Controller :
class CheckinController extends BaseRestController
{
/**
* #ApiDoc(
* resource=true,
* description="Find checkin by ID",
*
* parameters={
* {"name"="categoryId", "dataType"="integer", "required"=true, "description"="checkin id"}
* }
*
* output={
* "class"="Project1\ApiBundle\Entity\Checkins",
* "groups"={"checkin"}
* },
* statusCodes={
* 200="Checkin found",
* 400="ID is required",
* 404="Checkin not found"
* }
* )
*
* #Rest\View()
*/
public function getAction(Request $request)
{}
Result ( Description column is empty ) :
There's a description in doc section of the bundle:
For classes parsed with JMS metadata, description will be taken from the properties doc comment, if available.
For Form Types, you can add an extra option named description on each
field
Please visit the following link for more instructions(info at the bottom of the section):
https://github.com/nelmio/NelmioApiDocBundle/blob/master/Resources/doc/index.md#the-apidoc-annotation
Related
I have an object control with a lot of properties encapsuled. When i make a GET request /controls/{id} to get just one control i want more properties than GET request /controls who return me all my controls.
/**
* #ApiResource(
* formats={"json"},
* forceEager=false,
* itemOperations={
* "get"={
* "normalizationContext"={
* "groups"={"control:read"}
* }
* }
* },
* normalizationContext={"groups"={"fullcontrol:read"}, "enable_max_depth"=true})
* #ORM\Entity(repositoryClass=ControlRepository::class)
*/
class Control
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #Groups({"control:read"})
*/
private $id;
/**
* #ORM\OneToMany(targetEntity=Appointment::class, mappedBy="control", orphanRemoval=true)
* #Groups({"control:read"})
*/
private $appointments;
/**
* #ORM\OneToMany(targetEntity=ObjectEntity::class, mappedBy="control", cascade={"persist", "remove"})
* #Groups({"fullcontrol:read"})
*/
private $objectEntity;
Here my #ApiRessource header to do that. In the doc they explains the most specific normalizationContext will be used but it always use the control:read group and never the fullcontrol:read group
Anyone know how to make it working ?
I use Doctrine ORM and Gedmo\Slug and i have class with related entitty job with title field and i want generate slug by job title. I'm configured SlugHandler like this:
/**
*
* #Gedmo\Slug(handlers={
* #Gedmo\SlugHandler(class="Gedmo\Sluggable\Handler\RelativeSlugHandler", options={
* #Gedmo\SlugHandlerOption(name="relationField", value="job"),
* #Gedmo\SlugHandlerOption(name="relationSlugField", value="title"),
* #Gedmo\SlugHandlerOption(name="separator", value="-"),
* })
* }, fields={"slug"})
* #ORM\Column(type="string", unique=true, nullable=true)
*/
private $slug = '';
/**
* #var Job
*
* #ORM\OneToOne(targetEntity="Job", inversedBy="estimation")
* #ORM\JoinColumn(name="job_id", referencedColumnName="id", nullable = false)
*/
private $job;
But in slug field setting title value exactly the same as the title field value (without lowercase, separators and with spaces).
I don't understand what's the matter
If you suddenly encounter a similar problem, you need set option urilize in true:
/**
*
* #Gedmo\Slug(handlers={
* #Gedmo\SlugHandler(class="Gedmo\Sluggable\Handler\RelativeSlugHandler", options={
* #Gedmo\SlugHandlerOption(name="relationField", value="job"),
* #Gedmo\SlugHandlerOption(name="relationSlugField", value="title"),
* #Gedmo\SlugHandlerOption(name="separator", value="-"),
* #Gedmo\SlugHandlerOption(name="urilize", value="true"),
* })
* }, fields={"slug"})
* #ORM\Column(type="string", unique=true, nullable=true)
*/
private $slug;
I am using api-platform with Symfony 4. It works fine, but I would like to change a GET url from:
/booking/{id} to /booking/{bookingId}
I'm using my own DTO object and custom data provider (not Doctrine ORM).
Here are the current #ApiResource and #ApiProperty definitions that work fine:
/**
*
* #ApiResource(
* itemOperations={
* "get"={
* "path"="/booking/{id}",
* },
* "api_bookings_get_item"={
* "swagger_context"={
* "operationId"="getBookingItem",
* "summary"="Retrieves details on a booking",
* "parameters"= {
* {
* "name"="id",
* "description"="Booking ID",
* "default"="15000",
* "in"="path",
* "required"=true,
* "type"="string"
* }
* },
* "responses"={
* "200"={
* "description"="Results retrieved"
* },
* "404"={
* "description"="Booking not found"
* }
* }
* }
* }
* },
* collectionOperations={}
* )
*/
final class Booking
{
/**
* #var string
* #Assert\NotBlank
*
* #ApiProperty(
* identifier=true,
* attributes={
* "swagger_context"={
* "description"="Booking ID",
* "required"=true,
* "type"="string",
* "example"="123456"
* }
* }
* }
*/
public $id;
// other variables
}
However, if I change all the references from 'id' to 'bookingId' it stops working and I get a 404 error. Here are the changes I made to the above code:
"path"="/booking/{bookingId}"
"name"="bookingId"
public $bookingId;
Is api-platform hard-coded to use 'id' as an identifier? Is there any way to change this?
In Api-platform the id parameter is hardcoded:
namespace ApiPlatform\Core\DataProvider;
private function extractIdentifiers(array $parameters, array $attributes)
{
if (isset($attributes['item_operation_name'])) {
if (!isset($parameters['id'])) {
throw new InvalidIdentifierException('Parameter "id" not found');
}
but you can create your own operation and use the parameter name that you want there is a great example in docs custom operations
You can customize the apiResource identifier via:
/**
* #ApiProperty(identifier=false)
*/
private $id;
and:
/**
* #ApiProperty(identifier=true)
*/
private $uuid;
where uuid is the new identifier to be used in request URLs.
For reference: symfonycasts did an excellent tutorial here:
https://symfonycasts.com/screencast/api-platform-extending/uuid-identifier
Serialization groups work for me fine when i fetch one entity but
when i try fetch array of results i got empty result set.
I do this like that:
* #\FOS\RestBundle\Controller\Annotations\View(serializerGroups={"client"})
but also tried manually set context on view object, and same situation.
When i don't set group or set to "Default":
* #\FOS\RestBundle\Controller\Annotations\View(serializerGroups={"Default"})
i got proper serialized result set.
My entity:
use JMS\Serializer\Annotation as JMS;
[...]
/**
* Document
*
* #ORM\Table(name="documents")
* #ORM\Entity(repositoryClass="AppBundle\Entity\DocumentRepository")
* #ORM\EntityListeners({"DocumentListener"})
* #JMS\ExclusionPolicy("all")
* #JMS\AccessorOrder("custom", custom = {"id", "folderId", "title"})
*/
class Document implements ResourceInterface
{
/**
* #var integer
*
* #ORM\Column(type="integer", name="id")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #JMS\Groups({"client"})
* #JMS\Expose()
*/
protected $id;
/**
* #var string
*
* #ORM\Column(type="text", name="description")
* #JMS\Groups({"client"})
* #JMS\Expose()
*/
protected $description;
[...]
and my controller:
// not working
/**
* #\FOS\RestBundle\Controller\Annotations\View(serializerGroups={"client"})
* #return Paginator
* #Get("/documents")
*/
public function documentsAction(ParamFetcher $params)
{
[...]
return ($this->getPaginator(
$params,
$documentBundle->get()
));
}
//works fine
/**
* Get document
*
* #QueryParam(name="id", requirements="\d+", nullable=false)
* #param ParamFetcher $params
* #\FOS\RestBundle\Controller\Annotations\View(serializerGroups={"client"})
*/
public function documentAction(ParamFetcher $params)
{
/** #var DocumentRepository $documentBundle */
$documentBundle = $this->getDoctrine()->getRepository('AppBundle:Document');
return $documentBundle->findByDocumentId($params->get('id'));
}
PS.
fosrestbundle 1.7.9
jmsserializer 0.16.0
I am using Uploadable extension and very happy with that.
I have entity with one field as an Uploadable (photo), and another field is annotation for that photo (annotation). When I first create entity I choose the file, and put annotation and everything works okay, but when I want to update just annotation it loses the stored path of the previously uploaded photo. Is there a way to keep old values if null coming for that field?
This is my entity.
/**
* Photo
*
* #ORM\Table()
* #ORM\Entity
* #Gedmo\Uploadable(
* path="up/photo",
* allowOverwrite=false,
* appendNumber=true,
* allowedTypes="image/jpeg,image/pjpeg,image/png,image/x-png"
* )
*/
class Photo
{
/**
* #var array
*
* #Gedmo\Translatable
* #ORM\Column(name="annotation", type="string", length=255, nullable=true)
*/
private $annotation;
/**
* #var string
*
* #Gedmo\UploadableFilePath
* #Assert\File(
* mimeTypes={"image/jpeg", "image/pjpeg", "image/png", "image/x-png"}
* )
* #ORM\Column(name="photo", type="string", length=255)
*/
private $photo;
And this is my Controller part:
if ($entity->getPhoto()) {
$uploadableManager = $this->get('stof_doctrine_extensions.uploadable.manager');
$uploadableManager->markEntityToUpload($entity, $entity->getPhoto());
}
You can change setter on your entity:
public function setPhoto($photo) {
if (!$photo) {return $this;}
$this->photo = $photo;
return $this;