# Subresources A Subresource is another way of declaring a resource that usually involves a more complex URI. In API Platform you can declare as many `ApiResource` as you want on a PHP class creating Subresources. Subresources work very well by implementing your own state [providers](./state-providers.md) or [processors](./state-processors.md). In API Platform we provide a working Doctrine layer for subresources providing you add the correct configuration for URI Variables. ## URI Variables Configuration URI Variables are configured via the `uriVariables` node on an `ApiResource`. It's an array indexed by the variables present in your URI, `/companies/{companyId}/employees/{id}` has two uri variables `companyId` and `id`. For each of these, we need to create a `Link` between the previous and the next node, in this example the link between a Company and an Employee. If you're using the Doctrine implementation, queries are automatically built using the provided links. ### Answer to a Question For this example we have two classes, a Question and an Answer. We want to find the Answer to the Question about the Universe using the following URI: `/question/42/answer`. Let's start by defining the resources: ```php id; } // ... } // api/src/Entity/Question.php namespace App\Entity; use ApiPlatform\Metadata\ApiResource; use Doctrine\ORM\Mapping as ORM; #[ORM\Entity] #[ApiResource] class Question { #[ORM\Id, ORM\Column, ORM\GeneratedValue] private ?int $id = null; #[ORM\Column(type: 'text')] public string $content; #[ORM\OneToOne] #[ORM\JoinColumn(referencedColumnName: 'id', unique: true)] public Answer $answer; public function getId(): ?int { return $this->id; } // ... } ``` Now to create a new way of retrieving an Answer we will declare another resource on the `Answer` class. To make things work, API Platform needs informations about how to retrieve the `Answer` belonging to the `Question`, this is done by configuring the `uriVariables`: ```php new Link( fromClass: Question::class, fromProperty: 'answer' ) ], operations: [new Get()] )] class Answer { // ... } ``` In this example, we instructed API Platform that the `Answer` we retrieve comes **from** the **class** `Question` **from** the **property** `answer` of that class. URI Variables are defined using Links (`ApiPlatform\Metadata\Link`). A `Link` can be binded either from or to a class and a property. If we had a `relatedQuestions` property on the `Answer` we could retrieve the collection of related questions via the following definition: ```php #[ApiResource( uriTemplate: '/answers/{id}/related_questions.{_format}', uriVariables: [ 'id' => new Link(fromClass: Answer::class, fromProperty: 'relatedQuestions') ], operations: [new GetCollection()] )] ``` ### Company Employee's Note that in this example, we declared an association using Doctrine only between Employee and Company using a ManyToOne. There is no inverse association hence the use of `toProperty` in the URI Variables definition. The following declares a few subresources: * `/companies/{companyId}/employees/{id}` - get an employee belonging to a company * `/companies/{companyId}/employees` - get the company employee's ```php new Link(fromClass: Company::class, toProperty: 'company'), 'id' => new Link(fromClass: Employee::class), ], operations: [ new Get() ] )] #[ApiResource( uriTemplate: '/companies/{companyId}/employees', uriVariables: [ 'companyId' => new Link(fromClass: Company::class, toProperty: 'company'), ], operations: [ new GetCollection() ] )] class Employee { #[ORM\Id, ORM\Column, ORM\GeneratedValue] public ?int $id; #[ORM\Column] public string $name; #[ORM\ManyToOne(targetEntity: Company::class)] public ?Company $company; public function getId() { return $this->id; } } ``` Now let's add the Company class: ```php new Link(fromClass: Employee::class, fromProperty: 'company'), ], operations: [ new Get() ] )] class Company { // ... } ```