无法为类型的项目生成IRI [英] Unable to generate an IRI for the item of type

查看:103
本文介绍了无法为类型的项目生成IRI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我实际上是在基于以下条件构建API:

I am actually building an API based on:

  • symfony/flex:v1.0.61
  • symfony:v4.0.3
  • api-platform/api-pack:1.0.1版
  • api平台/核心:v2.1.4

CRUD操作易于实现.尽管如此, 自定义操作似乎并不简单

The CRUD operations were easy to implement. Nevertheless, the custom operation does not seem to be straightforward.

我要实现的自定义操作将仅基于给定的$slug返回一个App\Entity\Product.

The custom operation I am trying to implement will simply return a App\Entity\Product based on a given $slug.

  • 路线为:/api/products/by-slugs/{slug}
  • 方法是:GET
  • 操作类型为:itemOperations
  • the route is: /api/products/by-slugs/{slug}
  • the method is: GET
  • the operation type is: itemOperations

这是做事的方式:

产品资源的声明

<?php
// src/Entity/Product
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;
use ApiPlatform\Core\Annotation\ApiResource;
use Symfony\Component\Validator\Constraints as Assert;
use Gedmo\Mapping\Annotation as Gedmo;
use Symfony\Component\Serializer\Annotation\Groups;


/**
 * @ORM\Entity
 * @ORM\Table(name="product")
 * @ORM\Entity(repositoryClass="App\Repository\ProductRepository")
 * @ApiResource(attributes={"pagination_client_items_per_page"=true,
 *                          "filters"={"product.search"}
 *                         },
 *              collectionOperations={
 *                      "get"={
 *                      "method"="GET",
 *                      "normalization_context"={"groups"={"product_gets"}} },
 *                      "post"={
 *                      "method"="POST",
 *                      "denormalization_context"={"groups"={"product_post"}} }
 *              },
 *              itemOperations={
 *                      "get"={
 *                      "method"="GET",
 *                      "normalization_context"={"groups"={"product_get"}} },
 *                      "put"={
 *                      "method"="PUT",
 *                      "denormalization_context"={"groups"={"product_put"}} },
 *                      "delete"={
 *                      "method"="DELETE"},
 *                      "product_slug"={"route_name"="route_product_slug"}
 *              })
 * @ORM\HasLifecycleCallbacks()
 */

class Product{
}

ProductLoader的声明

<?php

namespace App\Loader;

use App\Entity\Product;
use Doctrine\ORM\EntityManagerInterface;
use Psr\Log\LoggerInterface;
use Psr\Cache\CacheItemPoolInterface;

class ProductLoader {
    private $em;
    private $logger;
    private $cache;

    public function __construct(
        EntityManagerInterface $em,
        LoggerInterface $logger,
        CacheItemPoolInterface $cache){
        $this->em = $em;
        $this->logger = $logger;
        $this->cache = $cache;
    }

    public function findBySlug($slug){
        return $this->em->getRepository(Product::class)->findProductBySlug($slug);
    }
}

产品存储库的声明

<?php

namespace App\Repository;

use Doctrine\ORM\EntityRepository;

/**
 * ProductRepository
 */
class ProductRepository extends EntityRepository {

    public function findProductBySlug($slug) {
        $qb = $this->createQueryBuilder("b")
                ->where("b.slug = :slug")
                ->setParameter('slug', $slug);
        return $qb->getQuery()->getOneOrNullResult();
    }

}

在Symfony控制器中声明自定义操作

<?php

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;

use App\Loader\ProductLoader;
use App\Entity\Product;

class ProductController extends Controller
{

    /**
     * @Route(
     *     name="route_product_slug",
     *     path="/api/products/by-slug/{slug}",
     *     defaults={"_api_resource_class"=Product::class,
     *               "_api_item_operation_name"="product_slug"
     *     }
     * )
     * @Method("GET")
     */
     public function productsGetBySlugAction(ProductLoader $productLoader, $slug){
        return $productLoader->findBySlug($slug);
     }
}

快速返回以下命令:

bin/console debug:router
 --------------------------------------- -------- -------- ------ --------------------------------------- 
  Name                                    Method   Scheme   Host   Path                                   
 --------------------------------------- -------- -------- ------ --------------------------------------- 
  app_product_products                    ANY      ANY      ANY    /                                      
  route_product_slug                      GET      ANY      ANY    /api/products/by-slug/{slug}           
  api_entrypoint                          ANY      ANY      ANY    /api/{index}.{_format}                 
  api_doc                                 ANY      ANY      ANY    /api/docs.{_format}                    
  api_jsonld_context                      ANY      ANY      ANY    /api/contexts/{shortName}.{_format}    
  api_products_get_collection             GET      ANY      ANY    /api/products.{_format}                
  api_products_post_collection            POST     ANY      ANY    /api/products.{_format}                
  api_products_get_item                   GET      ANY      ANY    /api/products/{id}.{_format}           
  api_products_put_item                   PUT      ANY      ANY    /api/products/{id}.{_format}           
  api_products_delete_item                DELETE   ANY      ANY    /api/products/{id}.{_format}           
  api_regions_get_collection              GET      ANY      ANY    /api/regions.{_format}                 
  api_regions_post_collection             POST     ANY      ANY    /api/regions.{_format}                 
  api_regions_get_item                    GET      ANY      ANY    /api/regions/{id}.{_format}            
  api_regions_put_item                    PUT      ANY      ANY    /api/regions/{id}.{_format}            
  api_regions_delete_item                 DELETE   ANY      ANY    /api/regions/{id}.{_format}            
  api_countries_get_collection            GET      ANY      ANY    /api/countries.{_format}               
  api_countries_post_collection           POST     ANY      ANY    /api/countries.{_format}               
  api_countries_get_item                  GET      ANY      ANY    /api/countries/{id}.{_format}          
  api_countries_put_item                  PUT      ANY      ANY    /api/countries/{id}.{_format}          
  api_countries_delete_item               DELETE   ANY      ANY    /api/countries/{id}.{_format}          
  api_countries_regions_get_subresource   GET      ANY      ANY    /api/countries/{id}/regions.{_format}  
  _twig_error_test                        ANY      ANY      ANY    /_error/{code}.{_format}               
  _wdt                                    ANY      ANY      ANY    /_wdt/{token}                          
  _profiler_home                          ANY      ANY      ANY    /_profiler/                            
  _profiler_search                        ANY      ANY      ANY    /_profiler/search                      
  _profiler_search_bar                    ANY      ANY      ANY    /_profiler/search_bar                  
  _profiler_phpinfo                       ANY      ANY      ANY    /_profiler/phpinfo                     
  _profiler_search_results                ANY      ANY      ANY    /_profiler/{token}/search/results      
  _profiler_open_file                     ANY      ANY      ANY    /_profiler/open                        
  _profiler                               ANY      ANY      ANY    /_profiler/{token}                     
  _profiler_router                        ANY      ANY      ANY    /_profiler/{token}/router              
  _profiler_exception                     ANY      ANY      ANY    /_profiler/{token}/exception           
  _profiler_exception_css                 ANY      ANY      ANY    /_profiler/{token}/exception.css       
 --------------------------------------- -------- -------- ------ --------------------------------------- 

路线route_product_slug已经存在,但是我总是遇到以下错误:

The route route_product_slug is well existing but I am always getting the following error:

无法为App \ Entity \ Product类型的项目生成IRI "

{
"@context": "/sf-flex-40/public/index.php/api/contexts/Error",
"@type": "hydra:Error",
"hydra:title": "An error occurred",
"hydra:description": "Unable to generate an IRI for the item of type \"App\\Entity\\Product\"",
"trace": [
    {
        "namespace": "",
        "short_class": "",
        "class": "",
        "type": "",
        "function": "",
        "file": "/home/amine/docker-projects/sf-flex-40/vendor/api-platform/core/src/Bridge/Symfony/Routing/IriConverter.php",
        "line": 107,
        "args": []
    },
    {
        "namespace": "ApiPlatform\\Core\\Bridge\\Symfony\\Routing",
        "short_class": "IriConverter",
        "class": "ApiPlatform\\Core\\Bridge\\Symfony\\Routing\\IriConverter",
        "type": "->",
        "function": "getIriFromItem",
        "file": "/home/amine/docker-projects/sf-flex-40/vendor/api-platform/core/src/JsonLd/Serializer/ItemNormalizer.php",
        "line": 71,
        "args": [
            [
                "object",
                "App\\Entity\\Product"
            ]
        ]
    },

该错误似乎经常发生.不过,我再次询问是因为问题似乎与我的启用Flex的symfony 4应用程序中的路由顺序不正确有关(请参阅

This error seems to be recurrent. Nevertheless, I am asking again since the problem seems to be related to bad order of routes in my flex-enable symfony 4 application (please refer to https://github.com/api-platform/core/issues/830).

因此,如果我在symfony 4中使用注释,如何设置路由的正确顺序.这些文件中定义了路由:

So, how can set the proper order of the routes if I am using the annotations in symfony 4. The routes are defined in these files:

第一个文件:annotations.yaml

# config/routes/annotations.yaml
controllers:
    resource: ../../src/Controller/
    type: annotation

第二个文件:api_platform.yaml

# config/routes/api_platform.yaml
api_platform:
    resource: .
    type: api_platform
    prefix: /api

这是否意味着我必须用YAML文件配置我的所有工作来代替注释,以便我可以指定路线的顺序?

Does this mean I have to configure all my work with YAML file in stead of annotations so that I can specify the order of the route?

谢谢

这是什么

推荐答案

只能通过 yaml文件声明自定义操作的路由.实际上,使用注释不会使我们正确的路线顺序.自定义操作的路径必须在声明路径api_platform之后.

The declaration of the route of the custom operation can only be through yaml file. In fact, the use of annotation will not us to get the correct order of routes. The route of the custom operation must come after the declaration of the route api_platform.

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

api_product_slug:
    path: '/api/products/by-slug/{slug}'
    methods:  ['GET']
    defaults:
        _controller: App\Controller\ProductController:productsGetBySlugAction
        _api_resource_class: 'App\Entity\Product'
        _api_collection_operation_name: 'product_slug'

这篇关于无法为类型的项目生成IRI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆