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

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

问题描述

我实际上正在基于以下内容构建 API:

I am actually building an API based on:

  • symfony/flex: v1.0.61
  • symfony: v4.0.3
  • api-platform/api-pack: v1.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

事情是这样进行的:

Product 资源的声明

<?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);
    }
}

ProductRepository 的声明

<?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);
     }
}

快速运行以下命令返回:

A quick run of the command below returned:

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 应用程序中的路由顺序错误有关(请参阅 https://github.com/api-platform/core/issues/830).

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天全站免登陆