0

I have problem with my Symfony rest API. I have this controller:

<?php

namespace App\Controller;

use App\Entity\Post;
use App\Service\ErrorDecoratorService;
use App\Service\PostService;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Serializer\SerializerInterface;

class PostController extends AbstractController
{
    private $postService;
    private $errorDecoratorService;

    public function __construct(PostService $postService, ErrorDecoratorService $errorDecoratorService)
    {
        $this->postService = $postService;
        $this->errorDecoratorService = $errorDecoratorService;
    }


    /**
     * @Route("/post/{postId}", methods={"GET"})
     * @param $postId
     * @param SerializerInterface $serializer
     * @return JsonResponse
     */
    public function getPost($postId, SerializerInterface $serializer)
    {
        $result = $this->postService->getPost($postId);
        if ($result instanceof Post) {

            $data = $serializer->serialize($result,'json');
            $status = JsonResponse::HTTP_OK;
        } else {
            $status = JsonResponse::HTTP_NOT_FOUND;
            $data = $this->errorDecoratorService->decorateError($status, $result);
        }
        return new JsonResponse($data, $status);
    }

}

When I have from database serialize to JSON format, then I receive this error:

Could not normalize object of type App\Entity\Post, no supporting normalizer found. (500 Internal Server Error)

It's my entity

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * @ORM\Entity(repositoryClass="App\Repository\PostRepository")
 */
class Post
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank()
     */
    private $title;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank()
     */
    private $content;

    /**
     * @ORM\Column(type="string", length=255)
     * @Assert\NotBlank()
     */
    private $author;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitle(): ?string
    {
        return $this->title;
    }

    public function setTitle(string $title): self
    {
        $this->title = $title;

        return $this;
    }

    public function getContent(): ?string
    {
        return $this->content;
    }

    public function setContent(string $content): self
    {
        $this->content = $content;

        return $this;
    }

    public function getAuthor(): ?string
    {
        return $this->author;
    }

    public function setAuthor(string $author): self
    {
        $this->author = $author;

        return $this;
    }
}

Where is my mistake? I have tried Symfony Serializer, JMS Serializer but I still get the same error.

yivi
  • 42,438
  • 18
  • 116
  • 138
PawelC
  • 1,128
  • 3
  • 21
  • 47
  • 1
    When I search google for your error message this is first result https://stackoverflow.com/a/52861797/6127393 – Arleigh Hix Sep 02 '19 at 03:44
  • Possible duplicate of [Symfony Serializer issue - NotNormalizableValueException](https://stackoverflow.com/questions/52861597/symfony-serializer-issue-notnormalizablevalueexception) – yivi Sep 02 '19 at 06:06
  • @ArleighHix I'll check this result – PawelC Sep 02 '19 at 06:36
  • @ArleighHix when i use tour link and add services, then in response i have "{\"id\":1,\"title\":\"qwerty\",\"content\":\"Lorem ipsum sit dolor amet\",\"author\":\"Pawel\"}" when I paste this code into the json validator it shows that it is not valid json – PawelC Sep 02 '19 at 15:09

1 Answers1

1

Once you enable the Normalizer the Serializer will produce a json encoded string with this line:

$data = $serializer->serialize($result,'json'); 
// "{\"id\":1,\"title\":\"qwerty\",\"content\":\"Lorem ipsum sit dolor amet\",\"author\":\"Pawel\"}"

The JsonResponse construct json encodes the first parameter, usually an array or object, but in your case just a string. You need to either decode the string when you pass it to the constructor, or preferably use the JsonResponse::fromJsonString() method.

Should work:

return new JsonResponse(json_decode($data), $status);

Preferred method:

return new JsonResponse::fromJsonString($data, $status);

https://symfony.com/doc/current/components/http_foundation.html#creating-a-json-response

Arleigh Hix
  • 9,990
  • 1
  • 14
  • 31
  • Now i have that https://pastebin.com/cJjUFV9i work fine, but is this code is good? it is good solution? working for sure. – PawelC Sep 02 '19 at 19:04
  • 1
    That should be just fine if it works for you. However the preferred method I provided would be better performance as it doesn't need to do any encoding/decoding and its better semantics in my opinion. – Arleigh Hix Sep 02 '19 at 20:01