question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Unable to use resource identifier

See original GitHub issue

The issue

I want to retrieve a resource by its slug thus I’m following the instructions on this page.

I’ve ended up with the following code:

<?php

declare(strict_types=1);

namespace Foo\Lt\Domain\Model\Page;

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

/**
 * @ORM\Table(name="pages", indexes={@ORM\Index(name="slug_index", columns={"slug"})})
 * @ORM\Entity(repositoryClass="Foo\Infrastructure\Domain\Model\Page\DoctrinePageRepository")
 *
 * @ApiResource(
 *     shortName="Pages",
 *     description="Miscellaneous pages.",
 *     routePrefix="v0",
 *     itemOperations={
 *         "get_page"={
 *              "method"="GET",
 *              "path"="/pages/{slug}",
 *              "requirements"={"slug"="\w+"},
 *              "swagger_context"= {
 *                  "summary"= "Retrieves a page.",
 *                  "description"= "Retrieves a page (i.e. help, terms, privacy)",
 *                  "parameters"= {
 *                      {
 *                          "in"= "path",
 *                          "name"= "slug",
 *                          "type"= "string",
 *                          "example"="help"
 *                      },
 *                  },
 *              },
 *          },
 *     },
 *     collectionOperations={
 *         "get"={"method"="GET"}
 *     },
 *     iri="pages",
 * )
 */
class Page
{
    /**
     * The unique auto incremented primary key.
     *
     * @var int|null
     *
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue
     */
    protected $id;

    /**
     * The page slug.
     *
     * @var string
     *
     * @ORM\Column(type="string", length=255, nullable=false)
     *
     * @ApiProperty(
     *     identifier=true,
     *     attributes={
     *         "swagger_context"={
     *             "type"="string",
     *             "description"="The page slug.",
     *             "example"="help"
     *         }
     *     },
     * )
     */
    protected $slug;

    /**
     * The page text.
     *
     * @var string
     *
     * @ORM\Column(type="text", nullable=false)
     *
     * @ApiProperty(
     *     attributes={
     *         "swagger_context"={
     *             "type"="string",
     *             "description"="The page text.",
     *             "example"="Foo bar baz",
     *         },
     *     }
     * )
     */
    protected $text;

    public function getId() : int
    {
        return $this->id;
    }

    public function getSlug() : string
    {
        return $this->slug;
    }

    public function getText() : string
    {
        return $this->text;
    }
}

Unfortunately a request to api/v0/pages/help will result in:

{
  "@context": "/api/contexts/Error",
  "@type": "hydra:Error",
  "hydra:title": "An error occurred",
  "hydra:description": "Not found, because of an invalid identifier configuration",
  "trace": [
    {
      "namespace": "",
      "short_class": "",
      "class": "",
      "type": "",
      "function": "",
      "file": "/var/www/app/vendor/api-platform/core/src/EventListener/ReadListener.php",
      "line": 102,
      "args": []
    },

What did not tell anything useful to me, so after removing the try catch from ReadListener the following exception has occurred:

{
  "@context": "/api/contexts/Error",
  "@type": "hydra:Error",
  "hydra:title": "An error occurred",
  "hydra:description": "Parameter \"id\" not found",
  "trace": [
    {
      "namespace": "",
      "short_class": "",
      "class": "",
      "type": "",
      "function": "",
      "file": "/var/www/app/vendor/api-platform/core/src/DataProvider/OperationDataProviderTrait.php",
      "line": 90,
      "args": []
    },

Notes

  • I do not need a collectionOperations but I’m declaring one because of this.
  • I’m using the iri annotation like suggested here in order to avoid the errors “No collection route associated with the type” and “Unable to generate an IRI for the item of type”
  • This issue is kinda messed because at the moment I’ve had a lot of problems trying to configure this simple entity/resource without coupling my domain logic with API Platform.

Issue Analytics

  • State:closed
  • Created 4 years ago
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

3reactions
gnumokshacommented, Apr 8, 2019

@soyuka Thanks for answering.

I have some questions:

  1. Using “@ApiProperty (identifier = true)” shouldn’t be sufficient to tell the API Platform to use only the slug?
  2. Should not this information be described at https://api-platform.com/docs/core/identifiers/?
  3. Could you provide an example of how to use a custom controller for this case? I’m still getting “Not Found, because of an invalid identifier configuration”

And, if it is not asking too much, can you provide an example of how to use API platform with only DTOs and serialization? At the moment I do not want to couple my application with the API platform’ way to do things so I only want API Platform to populate a DTO, receive it on a controller and serialize the response.

2reactions
soyukacommented, Mar 31, 2019

It can’t really work like this:

  • you’re declaring 2 identifiers (id and slug)
  • the route contains slug but Api Platform can’t request your data provider through this
  • it’ll try to use the request given id which isn’t in the route params

What you could do is use "path"="/pages/{id} and add a DataProvider that will handle id as a slug. Or do a custom operation with a custom controller.

We don’t have a way to match route params to an identifier like you want it to, I have a proposal here though: https://github.com/api-platform/core/pull/2126. You could maybe add this patch in your stack by overriding some services.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Unable to specify Resource Identifier for AWS::ApiGateway
I have defined the following resources: IAM Role so that APIGateway can invoke lambda functions. AWS::ApiGateway::RestApi; AWS::ApiGateway:: ...
Read more >
Looking Up Resources That Are Discovered by AWS Config
AWS Config lists the resources that match your search options. You can see the following information about the resources: Resource identifier – The...
Read more >
"Unable to find resource ID" when activity is in library module ...
The issue occurs with Android Studio 3.0 RC 1 + Kotlin Gradle/Maven artifacts 1.2.0-beta-88. You have to use butterknife 8.5.1 OR 9.0.0-SNAPSHOT from ......
Read more >
Resource not found errors - Azure Resource Manager
If you can't verify the properties, sign in to the Microsoft Azure portal. Find the resource you're trying to use and examine the...
Read more >
Resource IDs - Smile CDR Documentation
Changing it may cause FHIR resource IDs to change, resources to become inaccessible, or the module to fail to start. The algorithm used...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found