无法为该类型的项目生成 IRI [英] Unable to generate an IRI for the item of type
问题描述
我实际上正在基于以下内容构建 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屋!