无法为类型的项目生成 IRI
Unable to generate an IRI for the item of type
我实际上正在构建一个 API 基于:
- symfony/flex: v1.0.61
- symfony: v4.0.3
- api-platform/api-pack: v1.0.1
- api-platform/core: v2.1.4
CRUD 操作很容易实现。尽管如此,
custom operation好像不太直白
我尝试实现的自定义操作将只是 return 一个基于给定 $slug
.
的 App\Entity\Product
- 路线是:
/api/products/by-slugs/{slug}
- 方法是:
GET
- 操作类型为:
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);
}
}
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);
}
}
快速 运行 下面的命令 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
已经存在,但我总是收到以下错误:
无法为 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)。
那么,如果我使用 symfony 4 中的注释,如何设置正确的路由顺序。路由在这些文件中定义:
第一个文件: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 文件而不是注释来配置我的所有工作,以便我可以指定路由的顺序?
谢谢
这是什么
自定义操作的路由只能通过yaml文件声明。事实上,注释的使用不会让我们得到路由的正确顺序。自定义操作的路由必须在路由声明之后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'
我实际上正在构建一个 API 基于:
- symfony/flex: v1.0.61
- symfony: v4.0.3
- api-platform/api-pack: v1.0.1
- api-platform/core: v2.1.4
CRUD 操作很容易实现。尽管如此, custom operation好像不太直白
我尝试实现的自定义操作将只是 return 一个基于给定 $slug
.
App\Entity\Product
- 路线是:
/api/products/by-slugs/{slug}
- 方法是:
GET
- 操作类型为:
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);
}
}
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);
}
}
快速 运行 下面的命令 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
已经存在,但我总是收到以下错误:
无法为 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)。
那么,如果我使用 symfony 4 中的注释,如何设置正确的路由顺序。路由在这些文件中定义:
第一个文件: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 文件而不是注释来配置我的所有工作,以便我可以指定路由的顺序?
谢谢
这是什么
自定义操作的路由只能通过yaml文件声明。事实上,注释的使用不会让我们得到路由的正确顺序。自定义操作的路由必须在路由声明之后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'