Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Lucky you! You found an early release chapter - it will be fully polished and published shortly!

Relations Iri

This Chapter isn't
quite ready...

Rest assured, the gnomes are hard at work
completing this video!

Browse Tutorials

Coming soon...

When we tried to create this dragon treasure for the owner, we put the ID of an owner in the database and we found out the, A platform did not like that. It said expected. I r I. What is an iri? Well, if you go back down to the GI users collection endpoint, we know that every resource that comes from an API has an at ID on it set to the URL to where you can fetch that resource. This is the I R I I I stands for International Resource Identifier, and it's meant to be kind of like a unique identifier across your entire api. The number one is not a unique identifier, but this whole U URL is a unique identifier and as I've said, a U URL is all a heck of a lot more handy than just an integer id anyways, so when we want to set a relation property, we need to use the I R I slash API slash users slash one. When we hit execute, it works 2 0 1 status code, and when the owner comes back to us, it once again uses the iri. So the takeaway is that relations are just normal properties,

But we get and set them via their I R I string, and I just think this is such a beautiful and clean way to handle this. All right, let's talk about the other side of the relationship. I'm actually gonna refresh the whole page here and let's go to our get one user endpoint and let's fetch that user with ID one. And there's the basic data. So the question I have now is, could we add a treasure's field here that shows all the treasures that this user owns? Well, think about it. We know how the serializer works by just serializing the properties on user. And we do have a Dragon Treasures property on user. So let's expose this to our api. I'll add groups with just user calling read for now. Later we'll talk about what, how you can write to a collection field, but for now, just make it readable.

All right. When we refresh and go look at the same get end point down here, yeah, you can see Dragon Treasures is showing up in the example config. So let's try this. I'll use ID one again. It executes and ugh, gorgeous. What it gives us is an array of I R I strings. I love that. These are so powerful because if we need more information about these, we can make a request to these end points to get all of those treasure details. And if you get really fancy and use something like Vulcan, you could even preload those so that the server pushes to them. But I do kind of though, as cool as that is there is kind of one obvious question here, which is, what if I, what if needing the Dragon treasure data for a user is so common that to avoid the extra requests, we just want to embed the data right here, like objects of data, Jason, objects of data instead of these strings. Can we do that? Absolutely. Let's find, let's find out how next.

Leave a comment!

Login or Register to join the conversation
Cat in space

"Houston: no signs of life"
Start the conversation!

What PHP libraries does this tutorial use?

// composer.json
    "require": {
        "php": ">=8.1",
        "ext-ctype": "*",
        "ext-iconv": "*",
        "api-platform/core": "^3.0", // v3.0.8
        "doctrine/annotations": "^1.0", // 1.14.2
        "doctrine/doctrine-bundle": "^2.8", // 2.8.0
        "doctrine/doctrine-migrations-bundle": "^3.2", // 3.2.2
        "doctrine/orm": "^2.14", // 2.14.0
        "nelmio/cors-bundle": "^2.2", // 2.2.0
        "nesbot/carbon": "^2.64", // 2.64.1
        "phpdocumentor/reflection-docblock": "^5.3", // 5.3.0
        "phpstan/phpdoc-parser": "^1.15", // 1.15.3
        "symfony/asset": "6.2.*", // v6.2.0
        "symfony/console": "6.2.*", // v6.2.3
        "symfony/dotenv": "6.2.*", // v6.2.0
        "symfony/expression-language": "6.2.*", // v6.2.2
        "symfony/flex": "^2", // v2.2.4
        "symfony/framework-bundle": "6.2.*", // v6.2.3
        "symfony/property-access": "6.2.*", // v6.2.3
        "symfony/property-info": "6.2.*", // v6.2.3
        "symfony/runtime": "6.2.*", // v6.2.0
        "symfony/security-bundle": "6.2.*", // v6.2.3
        "symfony/serializer": "6.2.*", // v6.2.3
        "symfony/twig-bundle": "6.2.*", // v6.2.3
        "symfony/ux-react": "^2.6", // v2.6.1
        "symfony/validator": "6.2.*", // v6.2.3
        "symfony/webpack-encore-bundle": "^1.16", // v1.16.0
        "symfony/yaml": "6.2.*" // v6.2.2
    "require-dev": {
        "doctrine/doctrine-fixtures-bundle": "^3.4", // 3.4.2
        "symfony/debug-bundle": "6.2.*", // v6.2.1
        "symfony/maker-bundle": "^1.48", // v1.48.0
        "symfony/monolog-bundle": "^3.0", // v3.8.0
        "symfony/stopwatch": "6.2.*", // v6.2.0
        "symfony/web-profiler-bundle": "6.2.*", // v6.2.4
        "zenstruck/foundry": "^1.26" // v1.26.0