# Handling Relations
API Platform Admin handles `to-one` and `to-many` relations automatically.
Thanks to [the Schema.org support](schema.org.md), you can easily display the name of a related resource instead of its IRI.
## Embedded Relations
If a relation is an array of [embeddeds or an embedded](../core/serialization.md#embedding-relations) resource, the admin will keep them by default.
The embedded data will be displayed as text field and editable as text input: the admin cannot determine the fields present in it.
To display the fields you want, see [this section](handling-relations.md#display-a-field-of-an-embedded-relation).
You can also ask the admin to automatically replace the embedded resources' data by their IRI,
by setting the `useEmbedded` parameter of the Hydra data provider to `false`.
Embedded data is inserted to a local cache: it will not be necessary to make more requests if you reference some fields of the embedded resource later on.
```javascript
// admin/src/App.js
import { HydraAdmin, fetchHydra, hydraDataProvider } from '@api-platform/admin';
import { parseHydraDocumentation } from '@api-platform/api-doc-parser';
const entrypoint = process.env.REACT_APP_API_ENTRYPOINT;
const dataProvider = hydraDataProvider({
entrypoint,
httpClient: fetchHydra,
apiDocumentationParser: parseHydraDocumentation,
mercure: true,
useEmbedded: false,
});
export default () => (
);
```
## Display a Field of an Embedded Relation
If you have an [embedded relation](../core/serialization.md#embedding-relations) and need to display a nested field, the code you need to write depends of the value of `useEmbedded` of the Hydra data provider.
If `true` (default behavior), you need to use the dot notation to display a field:
```javascript
import {
HydraAdmin,
FieldGuesser,
ListGuesser,
ResourceGuesser,
} from '@api-platform/admin';
import { TextField } from 'react-admin';
const BooksList = (props) => (
{/* Use react-admin components directly when you want complex fields. */}
);
export default () => (
);
```
If `useEmbedded` is explicitly set to `false`, make sure you write the code as if the relation needs to be fetched as a reference.
In this case, you _cannot_ use the dot separator to do so.
Note that you cannot edit the embedded data directly with this behavior.
For instance, if your API returns:
```json
{
"@context": "/contexts/Book",
"@id": "/books",
"@type": "Collection",
"member": [
{
"@id": "/books/07b90597-542e-480b-a6bf-5db223c761aa",
"@type": "https://schema.org/Book",
"title": "War and Peace",
"author": {
"@id": "/authors/d7a133c1-689f-4083-8cfc-afa6d867f37d",
"@type": "https://schema.org/Author",
"firstName": "Leo",
"lastName": "Tolstoi"
}
}
],
"totalItems": 1
}
```
If you want to display the author first name in the list, you need to write the following code:
```javascript
import {
HydraAdmin,
FieldGuesser,
ListGuesser,
ResourceGuesser,
} from '@api-platform/admin';
import { ReferenceField, TextField } from 'react-admin';
const BooksList = (props) => (
{/* Use react-admin components directly when you want complex fields. */}
);
export default () => (
);
```
## Using an Autocomplete Input for Relations
Let's go one step further thanks to the [customization capabilities](customizing.md) of API Platform Admin by adding autocompletion support to form inputs for relations.
Let's consider an API exposing `Review` and `Book` resources linked by a `many-to-one` relation (through the `book` property).
This API uses the following PHP code:
```php
reviews = new ArrayCollection();
}
}
```
Notice the "partial search" [filter](../core/filters.md) on the `title` property of the `Book` resource class.
Now, let's configure API Platform Admin to enable autocompletion for the relation selector:
```javascript
import {
HydraAdmin,
ResourceGuesser,
CreateGuesser,
EditGuesser,
InputGuesser,
} from '@api-platform/admin';
import { ReferenceInput, AutocompleteInput } from 'react-admin';
const ReviewsCreate = (props) => (
({ title: searchText })}
optionText="title"
label="Books"
/>
);
const ReviewsEdit = (props) => (
({ title: searchText })}
optionText="title"
label="Books"
/>
);
export default () => (
);
```
If the book is embedded into a review and if the `useEmbedded` parameter is `true` (default behavior),
you need to change the `ReferenceInput` for the edit component:
```javascript
import {
HydraAdmin,
ResourceGuesser,
CreateGuesser,
EditGuesser,
InputGuesser,
} from '@api-platform/admin';
import { ReferenceInput, AutocompleteInput } from 'react-admin';
const ReviewsCreate = (props) => (
({ title: searchText })}
optionText="title"
label="Books"
/>
);
const ReviewsEdit = (props) => (
({ title: searchText })}
format={(v) => v['@id'] || v}
optionText="title"
label="Books"
/>
);
export default () => (
);
```
The autocomplete field should now work properly!