Flag of Ukraine
SymfonyCasts stands united with the people of Ukraine

Installing API Platform

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

Hello and welcome you beautiful people, to a tutorial that's near and dear to my heart: how to build magnificent castles with Legos. Oh, that would be awesome, wouldn't it? But really, we're here to talk about API Platform Version 3, which I promise is as fun as playing with Legos. Just don't tell my son I said that.

API Platform is, very simply, a tool on top of Symfony that allows us to build powerful APIs and love the process! It's been around for years and, honestly, it's crushing it. They have their own dedicated conference and, they've really outdone themselves with the latest version 3.

If you're new to API Platform, I wouldn't blame you if you said:

Come on Ryan... creating an API isn't that hard. It's just returning JSON: a bunch of squigglies and brackets!

Ok, that is true (at least for the first few endpoints). But wow are there a lot of little details to keep track of. For example, if you have an API that returns product data, you'll want that product JSON to be returned in the same way with the same fields, across all endpoints. That process is called serialization. On top of that, a lot of APIs now return extra fields that describes what the data means. We're going to see and talk about something called "JSON-LD", which does exactly that.

What else? How about documentation? Ideally interactive documentation that's generated automatically... because we do not want to build and maintain that by hand. Even if you're building an API just for yourself, having documentation is awesome. Paginating collections is also super important, filtering and searching collections, validation and content-type negotiation, which is where that same product could be returned as JSON, CSV, or another format. So yes, creating an API endpoint is easy. But creating a rich API is another thing entirely. And that's the point of API Platform. Oh, and if you're familiar with API Platform Version 2, version 3 will feel very familiar. It's just cleaner, more modern, and more powerful. So get out your Legos, and let's do this!

The API Platform Distribution

There are two ways to install API Platform. If you find their site and click into the documentation, you'll see them talk about the API Platform "Distribution". This is pretty cool! It's a completely pre-made project with Docker that gives you a place to build your API with Symfony, a React admin area, scaffolding to create a Next.js frontend and more. Heck, it even gives you a production-ready web server with extra tools like Mercure for real-time updates. It's the most powerful way to use API Platform.

But... in this tutorial, we're not going to use it. I hate nice things! No, we'll start our Lego project from scratch: with a perfectly normal and boring Symfony app. Why? Because I want you to see exactly how everything works under the hood. Then, if you want to use this Distribution later on, you totally can.

Project Setup & Our Project

Okay, to be a true "API Platform JSON Returning Champion", you should code along with me! Download the source code from this page. And after unzipping it, you'll find a start/ directory with the same code that you see here. This is a brand new Symfony 6.2 project with... absolutely nothing in it. Open up this README.md file for all the setup instructions. The last step will be to open the project in a terminal and use the Symfony binary to run:

symfony serve -d

This starts a local web server at 127.0.0.1:8000. I'll cheat and click that link to open up... a completely empty Symfony 6.2 project. There's literally nothing here except for this demo homepage.

What are we going to build? As we all know, the internet is missing something terribly important: an application for dragons to boast about their stolen treasures! Because if there's one thing a dragon likes more than treasure, it's bragging about it. Yup, we'll create a rich API that lets tech savvy dragons post new treasures, fetch treasures, search treasures from other dragons, etc. And yes, I did just finish reading the Hobbit.

Installing API Platform

So, let's get API Platform installed! Spin back over to your terminal and run:

composer require api

This is a Symfony Flex alias. Up here, you can see it's actually installing something called api-platform/api-pack. If you're not familiar, a "pack" in Symfony is, kind of a fake package, that allows you to easily install a set of packages. If you scroll down, it installed api-platform itself, Doctrine, since I didn't already have that, and some other packages. At the bottom... let's see... the doctrine-bundle recipe is asking us if we want to include a docker-compose.yml file to help add a database to our project. How nice of it! This is optional, but I'm going to say "p" for "Yes permanently". And... done!

The first thing to see is in the composer.json file:

85 lines composer.json
{
... lines 2 - 5
"require": {
"php": ">=8.1",
"ext-ctype": "*",
"ext-iconv": "*",
"api-platform/core": "^3.0",
"doctrine/annotations": "^1.0",
"doctrine/doctrine-bundle": "^2.8",
"doctrine/doctrine-migrations-bundle": "^3.2",
"doctrine/orm": "^2.14",
"nelmio/cors-bundle": "^2.2",
"phpdocumentor/reflection-docblock": "^5.3",
"phpstan/phpdoc-parser": "^1.15",
"symfony/asset": "6.2.*",
"symfony/console": "6.2.*",
"symfony/dotenv": "6.2.*",
"symfony/expression-language": "6.2.*",
"symfony/flex": "^2",
"symfony/framework-bundle": "6.2.*",
"symfony/property-access": "6.2.*",
"symfony/property-info": "6.2.*",
"symfony/runtime": "6.2.*",
"symfony/security-bundle": "6.2.*",
"symfony/serializer": "6.2.*",
"symfony/twig-bundle": "6.2.*",
"symfony/validator": "6.2.*",
"symfony/yaml": "6.2.*"
},
... lines 33 - 83
}

As promised, that API Platform pack added a bunch of packages into our project. Technically, these aren't all required, but this is going to give us a really rich experience building our API. And if you run

git status

... yep! It updated the usual files... and also added a bunch of config files for the new packages. It looks like there's a lot... but looks can be deceiving. All of these directories are empty... and the config files are small and simple. We also have some docker-compose files that we'll use in a minute to spin up a database.

So... now that API Platform is installed... did that give us anything yet? It did! And it's cool! Go back to the browser and head to /api. Whoa! We have an API documentation page! It's empty because we don't, ya know, actually have an API just yet, but this is going to come to life very soon.

Next: Let's create our first Doctrine entity and "expose" that as an API Resource. It's time for some magic.

Leave a comment!

7
Login or Register to join the conversation
Michal-K Avatar
Michal-K Avatar Michal-K | posted 2 days ago | edited

Hi! I have a question. Will this course work well with Symfony 5? :D
I mean, will it work the same as if it had Symfony 5? :D

Reply

Hey Michal!

Hmm. The problem is that API Platform 3 requires Symfony 6. So if you're using API Platform with Symfony 5, then I think you're using version 2.7, not 3. However, 2.7 and 3.0 are identical, except that deprecated items have been removed in 3.0. And, if you're using 2.7, you should set the metadata_backward_compatibility_layer flag to false - ref https://api-platform.com/docs/core/upgrade-guide/#im-migrating-from-26-and-want-to-prepare-for-30

If you do that, then yes, I think we very few exceptions, the tutorial will work fine for Symfony 5 and API Platform 2.7. If you hit any snags, you can let us know and we'll do our best to help!

Cheers!

1 Reply
vishajr Avatar
vishajr Avatar vishajr | posted 11 days ago

Hi Ryan, I just jumped into API Platform and it's pretty confusing to me.

I am planning to go through the API Platform 2 first since it has the security related content.

Is it okay or shall I just wait for API Platform 3 and start from there? Thanks!

Reply

Hey Vishajr,

The more you watch - the more you know ;) So, feel free to jump into ApiPlatform v2 tutorials first if you need it now, because releasing same tutorials on v3 will take some time. So it makes sense to start from those tutorials that are already recorded if you don't want to simply wait for new ones. But later, when v3 tutorials will be released - you can watch it again and I bet you will discover more new things for yourself, or even better understand it because you will have some base after old tutorials :)

Also, we added some notes in our v2 tutorials mentioning some differences and BC breaks, so it should help you as well ;)

Cheers!

Reply
kyotomano Avatar
kyotomano Avatar kyotomano | posted 12 days ago

Hi! Is this course going to be divided into 3 parts just like api platform 2? [base, security, custom resources]. I also have more questions. Are you going to cover Mercure? When are you going to release all 3 parts (I read comment from SC team member who claimed that it would be released by the end of the year, but it was 3 months ago)? Btw. Great pick. V3 seems to be much different than V2

Reply

Hi kyotomano!

This is a perfect time to ask these questions :).

Is this course going to be divided into 3 parts just like api platform 2? [base, security, custom resources].

Probably, yes. Though there are a few things that I need to look into - like much better support in API Platform 3 for DTO objects - that might affect exactly what's in each episode or how we split it all up.

Are you going to cover Mercure?

I wasn't planning on it... at least not in any big way. But is that something you're interested with in regards to API Platform? What are you hoping to use it for?

When are you going to release all 3 parts (I read comment from SC team member who claimed that it would be released by the end of the year, but it was 3 months ago)? Btw. Great pick. V3 seems to be much different than V2

Yea :/. The conference and holidays slowed things down. I don't know when... but I'm really hoping to dive through all 3 as quickly as possible vs ep 1, a break, ep2, a break, ep 3, which I know is annoying for everyone.

If there are some specific things that you'd like to see in the more advanced tutorials, now is a great time to let me know!

Cheers!

1 Reply
kyotomano Avatar

Thanks for your great and detailed answer. No, no. I don't expect to see Mercure in any "heavy" way/use. But would be cool to see it in action with api platform - 2 maybe 3 episodes (just like in symfony ux tutorial). I just find Mercure an interesting part that wasn't covered in any tutorial before and Api platform seems just right place to do it. There is also lack of such content. You have symfony docs where they explain how to set it up (a little too much in my opinion, should be divided into parts like: docker, binary and then setup with example - quick setup and detailed setup like .yaml) and use, but there is a lack of real example usage. On Api Platform website is example of chat, but lack of repo on GitHub to check code to see how it works. There is only one YT tutorial that is outdated about Mercure (and based on that, many people in comments ask and complain about not being able to set it up and learn - cause there is indeed no learning resource except docs => check Laravel and pusher, there is a lot of examples and even whole tutorials about that topic on YT or Laracasts). That's why I asked about that.

Reply
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
    }
}