api-platform.com Unable to generate an IRI for the

2019-06-09 19:22发布

I'm trying to setup my first api-platform instance and have run into some presumably noob questions around IDE. What I'm trying to do is setting up an register and reset entity in order to deal with registrations and password reminders from an app. And then have the entity's passed to a custom controller to do some checks, balances and mails afterwards (haven’t gotten around to that yet). But I keep running into this error when posting to my custom entities:

{
    "@context": "/api/contexts/Error",
    "@type": "hydra:Error",
    "hydra:title": "An error occurred",
    "hydra:description": "Unable to generate an IRI for the item of type \"App\\XXX\\UserBundle\\Entity\\Register\"",
    "trace": [
        {
            "namespace": "",
            "short_class": "",
            "class": "",
            "type": "",
            "function": "",
            "file": "/var/www/webservice/vendor/api-platform/core/src/Bridge/Symfony/Routing/IriConverter.php",
            "line": 116,
            "args": []
        },
        {
            "namespace": "ApiPlatform\\Core\\Bridge\\Symfony\\Routing",
            "short_class": "IriConverter",
            "class": "ApiPlatform\\Core\\Bridge\\Symfony\\Routing\\IriConverter",
            "type": "->",
            "function": "getIriFromItem",
            "file": "/var/www/webservice/vendor/api-platform/core/src/JsonLd/Serializer/ItemNormalizer.php",
            "line": 71,
            "args": [
                [
                    "object",
                    "App\\XXX\\UserBundle\\Entity\\Register"
                ]
            ]
        },
        {
            "namespace": "ApiPlatform\\Core\\JsonLd\\Serializer",
            "short_class": "ItemNormalizer",
            "class": "ApiPlatform\\Core\\JsonLd\\Serializer\\ItemNormalizer",
            "type": "->",
            "function": "normalize",
            "file": "/var/www/webservice/vendor/symfony/serializer/Serializer.php",
            "line": 138,
            "args": [
                [
                    "object",
                    "App\\XXX\\UserBundle\\Entity\\Register"
                ],
                [
                    "string",
                    "jsonld"
                ],
                [
                    "array",
                    {
                        "collection_operation_name": [
                            "string",
                            "post"
                        ],
                        "operation_type": [
                            "string",
                            "collection"
                        ],
                        "resource_class": [
                            "string",
                            "App\\XXX\\UserBundle\\Entity\\Register"
                        ],
                        "request_uri": [
                            "string",
                            "/api/register"
                        ],
                        "uri": [
                            "string",
                            "http://webservice.local/api/register"
                        ],
                        "resources": [
                            "object",
                            "ApiPlatform\\Core\\Serializer\\ResourceList"
                        ],
                        "jsonld_has_context": [
                            "boolean",
                            true
                        ]
                    }
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\Serializer",
            "short_class": "Serializer",
            "class": "Symfony\\Component\\Serializer\\Serializer",
            "type": "->",
            "function": "normalize",
            "file": "/var/www/webservice/vendor/symfony/serializer/Serializer.php",
            "line": 111,
            "args": [
                [
                    "object",
                    "App\\XXX\\UserBundle\\Entity\\Register"
                ],
                [
                    "string",
                    "jsonld"
                ],
                [
                    "array",
                    {
                        "collection_operation_name": [
                            "string",
                            "post"
                        ],
                        "operation_type": [
                            "string",
                            "collection"
                        ],
                        "resource_class": [
                            "string",
                            "App\\XXX\\UserBundle\\Entity\\Register"
                        ],
                        "request_uri": [
                            "string",
                            "/api/register"
                        ],
                        "uri": [
                            "string",
                            "http://webservice.local/api/register"
                        ],
                        "resources": [
                            "object",
                            "ApiPlatform\\Core\\Serializer\\ResourceList"
                        ]
                    }
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\Serializer",
            "short_class": "Serializer",
            "class": "Symfony\\Component\\Serializer\\Serializer",
            "type": "->",
            "function": "serialize",
            "file": "/var/www/webservice/vendor/api-platform/core/src/EventListener/SerializeListener.php",
            "line": 67,
            "args": [
                [
                    "object",
                    "App\\XXX\\UserBundle\\Entity\\Register"
                ],
                [
                    "string",
                    "jsonld"
                ],
                [
                    "array",
                    {
                        "collection_operation_name": [
                            "string",
                            "post"
                        ],
                        "operation_type": [
                            "string",
                            "collection"
                        ],
                        "resource_class": [
                            "string",
                            "App\\XXX\\UserBundle\\Entity\\Register"
                        ],
                        "request_uri": [
                            "string",
                            "/api/register"
                        ],
                        "uri": [
                            "string",
                            "http://webservice.local/api/register"
                        ],
                        "resources": [
                            "object",
                            "ApiPlatform\\Core\\Serializer\\ResourceList"
                        ]
                    }
                ]
            ]
        },
        {
            "namespace": "ApiPlatform\\Core\\EventListener",
            "short_class": "SerializeListener",
            "class": "ApiPlatform\\Core\\EventListener\\SerializeListener",
            "type": "->",
            "function": "onKernelView",
            "file": "/var/www/webservice/vendor/symfony/event-dispatcher/EventDispatcher.php",
            "line": 212,
            "args": [
                [
                    "object",
                    "Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent"
                ],
                [
                    "string",
                    "kernel.view"
                ],
                [
                    "object",
                    "Symfony\\Component\\EventDispatcher\\EventDispatcher"
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\EventDispatcher",
            "short_class": "EventDispatcher",
            "class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
            "type": "->",
            "function": "doDispatch",
            "file": "/var/www/webservice/vendor/symfony/event-dispatcher/EventDispatcher.php",
            "line": 44,
            "args": [
                [
                    "array",
                    [
                        [
                            "array",
                            [
                                [
                                    "object",
                                    "ApiPlatform\\Core\\Validator\\EventListener\\ValidateListener"
                                ],
                                [
                                    "string",
                                    "onKernelView"
                                ]
                            ]
                        ],
                        [
                            "array",
                            [
                                [
                                    "object",
                                    "ApiPlatform\\Core\\EventListener\\WriteListener"
                                ],
                                [
                                    "string",
                                    "onKernelView"
                                ]
                            ]
                        ],
                        [
                            "array",
                            [
                                [
                                    "object",
                                    "ApiPlatform\\Core\\EventListener\\SerializeListener"
                                ],
                                [
                                    "string",
                                    "onKernelView"
                                ]
                            ]
                        ],
                        [
                            "array",
                            [
                                [
                                    "object",
                                    "ApiPlatform\\Core\\EventListener\\RespondListener"
                                ],
                                [
                                    "string",
                                    "onKernelView"
                                ]
                            ]
                        ]
                    ]
                ],
                [
                    "string",
                    "kernel.view"
                ],
                [
                    "object",
                    "Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent"
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\EventDispatcher",
            "short_class": "EventDispatcher",
            "class": "Symfony\\Component\\EventDispatcher\\EventDispatcher",
            "type": "->",
            "function": "dispatch",
            "file": "/var/www/webservice/vendor/symfony/http-kernel/HttpKernel.php",
            "line": 154,
            "args": [
                [
                    "string",
                    "kernel.view"
                ],
                [
                    "object",
                    "Symfony\\Component\\HttpKernel\\Event\\GetResponseForControllerResultEvent"
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\HttpKernel",
            "short_class": "HttpKernel",
            "class": "Symfony\\Component\\HttpKernel\\HttpKernel",
            "type": "->",
            "function": "handleRaw",
            "file": "/var/www/webservice/vendor/symfony/http-kernel/HttpKernel.php",
            "line": 66,
            "args": [
                [
                    "object",
                    "Symfony\\Component\\HttpFoundation\\Request"
                ],
                [
                    "integer",
                    1
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\HttpKernel",
            "short_class": "HttpKernel",
            "class": "Symfony\\Component\\HttpKernel\\HttpKernel",
            "type": "->",
            "function": "handle",
            "file": "/var/www/webservice/vendor/symfony/http-kernel/Kernel.php",
            "line": 188,
            "args": [
                [
                    "object",
                    "Symfony\\Component\\HttpFoundation\\Request"
                ],
                [
                    "integer",
                    1
                ],
                [
                    "boolean",
                    true
                ]
            ]
        },
        {
            "namespace": "Symfony\\Component\\HttpKernel",
            "short_class": "Kernel",
            "class": "Symfony\\Component\\HttpKernel\\Kernel",
            "type": "->",
            "function": "handle",
            "file": "/var/www/webservice/public/index.php",
            "line": 37,
            "args": [
                [
                    "object",
                    "Symfony\\Component\\HttpFoundation\\Request"
                ]
            ]
        }
    ]
}

I did of course do some research on my own and had a look at both:

So I've added an id (which is not needed since this entity is just used for post's), cleared the cash, checked the getters and setters but all to no avail.

The entity currently looks like this

/**
 * The register Entity
 *
 * @ApiResource(
 *      collectionOperations={
 *          "post"={"method"="POST", "path"="/register", "controller" = RegisterController::class}          
 *      }
 * )
 */

class Register implements \Serializable
{
    /**
     * The unique identifier of this user <br /><b>Schema:</b> <a href="http://schema.org/identifier">https://schema.org/identifier</a>
     *
     * @var integer
     *
     * @ApiProperty(iri="https://schema.org/identifier", identifier=true)
     */
    protected $id;  

    /**
     * The unique username of this user, used as a security credential alongside the password
     * 
     * @var string
     *
     */
    protected $username;

    /**
     * The non-unique e-mail address, used to contact the user on security issues
     * 
     * @var string
     *
     * @ApiProperty(iri="http://schema.org/email")
     */
    protected $email;

    /**
     * The non-unique password of this user, used as a security credential alongside the e-mail. Passwords are hashed in the database and can therefore never be rendered or viewed
     * 
     * @var string
     *
     */
    protected $password;

    /**
     * Serializing the user data that is set into the session
     */
    /** @see \Serializable::serialize() */
    public function serialize()
    {
        return serialize(array(
                $this->id,
                $this->username,
                $this->password,
                $this->email
        ));
    }

    /** @see \Serializable::unserialize() */
    public function unserialize($serialized)
    {
        list (
                $this->id,
                $this->username,
                $this->password,
                $this->email,
                ) = unserialize($serialized);
    }


    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Get id.
     *
     * @return User
     */
    public function setId($id)
    {
        $this->id= $id;

        return $this;
    }   

    /**
     * Set username
     *
     * @param string $username
     *
     * @return User
     */
    public function setUsername($username)
    {
        $this->username = $username;

        return $this;
    }

    public function getUsername()
    {
        return $this->username;
    }

    /**
     * Set password
     *
     * @param string $password
     *
     * @return User
     */
    public function setPassword($password)
    {
        $this->password = $password;

        return $this;
    }

    public function getPassword()
    {
        return $this->password;
    }


    /**
     * Set email.
     *
     * @param string $email
     *
     * @return User
     */
    public function setEmail($email)
    {
        $this->email = $email;

        return $this;
    }

    /**
     * Get email.
     *
     * @return string
     */
    public function getEmail()
    {
        return $this->email;
    }
}

The controller (not quite finished but trying to solve this first):

/**
 * Register controller
 *
 * @category   Controller
 * @package    XXX\UserBundle
 * @subpackage Controller
 *
 */

namespace App\XXX\UserBundle\Controller;


use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use App\XXX\UserBundle\Service\UserService;
use App\XXX\UserBundle\Entity\User;
use App\XXX\UserBundle\Entity\Register;

class RegisterController extends Controller
{
    private $userService;

    public function __construct(UserService $userService)
    {
        $this->userService= $userService;
    }

    public function __invoke(Register $data): Register
    {
        //$this->myService->doSomething($data);

        /*
        $user = $this->userService->register($data);

        if($user){
            //  $token = JWTManager::create($user)

            // voorbeeld

            // return serialized token
            // @var JWTManager $jwtManager 
            $jwtManager = $this->get('lexik_jwt_authentication.jwt_manager');
            $jwt = $jwtManager->create($user);
            $response = new JsonResponse();
            $response->setData(array('token' => $jwt));
            return $response;
        }
         */
        return $data;
    }


}

and last but not least config/routes/api_platform.yaml

api_platform:
    resource: .
    type: api_platform
    prefix: /api


user_register:
    path: '/api/register'
    methods:  ['POST']
    defaults:
        _controller: '\App\XXX\UserBundle\RegisterController::class'
        _api_resource_class: 'App\XXX\UserBundle\Entity\Register'
        _api_item_operation_name: 'register'

user_reminder:
    path: '/api/reset'
    methods:  ['POST']
    defaults:
        _controller: '\App\XXX\UserBundle\ResetController::class'
        _api_resource_class: 'App\XXX\UserBundle\Entity\Reset'
        _api_item_operation_name: 'rest'

user_login:
    path: '/api/login'
    methods:  ['POST']
    defaults:
        _controller: '\App\XXX\UserBundle\LoginController::class'
        _api_resource_class: 'App\XXX\UserBundle\Entity\Login'
        _api_item_operation_name: 'login'

I'm probably overlooking something basic here, but I've spent hours on it and just can't seem to get it to work.

--- Update --- I changed everything back to basic (for testing and error hunting) and it just wont fly. Added get/set and even made ID public, it just wont work. Even this simple class below gets me the IRI error. So basically everything I try that isn't an ORM object fails.

use ApiPlatform\Core\Annotation\ApiProperty;
use ApiPlatform\Core\Annotation\ApiResource;

/**
 * The user Entity
 *
 * @ApiResource(
 *      itemOperations={
 *          "get"={"method"="GET"},
 *      },
 *      collectionOperations={
 *          "get"={"method"="GET"},
 *          "register"={"route_name"="register_register"},
 *      },
 * )
 */

class Register 
{
    /**
     * The unique identifier of this user <br /><b>Schema:</b> <a href="http://schema.org/identifier">https://schema.org/identifier</a>
     * 
     * @var integer
     *
     * @ApiProperty(identifier=true)
     */
    public  $id;    


    /**
     * Get id.
     *
     * @return int
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }


    /**
     * Get id.
     *
     * @return int
     */
    public function getId()
    {
        return $this->id;
    }
}

2条回答
霸刀☆藐视天下
2楼-- · 2019-06-09 19:49

did you have a look at this thread api platform - Unable to generate an IRI for the item

Usually this error happen when property Id is not accessible

查看更多
淡お忘
3楼-- · 2019-06-09 19:58

I am new to api platform and had the same issue. The following solution worked for me. Add a normalization_context to the post method in collectionOperations annotation section.

Using your first Register class you would have:

/**
     * The register Entity
     *
     * @ApiResource(
     *      collectionOperations={
     *          "post"=
     *           {
     *              "method"="POST",
     *              "path"="/register",
     *              "controller" = RegisterController::class,
     *              "normalization_context"={"groups"={"common:read"}}
     *           }          
     *      }
     * )
     */

    class Register implements \Serializable
    {

Then put the same group above the fields/properties you wish to return. Continuing with the Register class above: the value added above each property is @Groups("common:read") :

/**
     * The unique identifier of this user <br /><b>Schema:</b> <a href="http://schema.org/identifier">https://schema.org/identifier</a>
     *
     * @var integer
     *
     * @Groups("common:read")
     *
     * @ApiProperty(iri="https://schema.org/identifier", identifier=true)
     */
    protected $id;  

    /**
     * The unique username of this user, used as a security credential alongside the password
     * 
     * @var string
     *
     * @Groups("common:read")
     *
     */
    protected $username;

    /**
     * The non-unique e-mail address, used to contact the user on security issues
     * 
     * @var string
     *
     * @Groups("common:read")
     *
     * @ApiProperty(iri="http://schema.org/email")
     */
    protected $email;
查看更多
登录 后发表回答