We use cookies on this site to enhance your user experience. By clicking "OK, I Agree" or using our site, you consent to the use of cookies unless you have disabled them.
View our cookie policy to learn more.

Yo friends! It's time to talk about... drum roll... how to bake a delicious cake that looks like an Oreo. Wait... ah! Wrong tutorial. It's time to talk about API Platform... so fun, it's almost as delicious as a cake shaped like an Oreo.

API Platform is crushing it these days. I feel like everywhere I turn, someone is raving about it! Its lead developer - Kévin Dunglas - is a core contributor of Symfony, super nice guy and is absolutely pushing the boundaries of what API's can do. We're going to see that first-hand. He was also nice enough to guide us on this tutorial!

If you only need to build a few API endpoints just to support some JavaScript, you might be thinking:

What's the big deal? Returning some JSON here and there is already pretty easy!

I've had this same opinion for awhile. But little-by-little, I think this is becoming less and less true. Just like how frameworks were born when web apps became more and more complex, tools like API Platform have been created because the same things is currently happening with APIs.

These days, API's are more than just returning JSON: it's about being able to serialize and deserialize your models consistently, maybe into multiple formats, like JSON or XML, but also JSON-LD or HAL JSON. Then there's hypermedia, linked data, status codes, error formats, documentation - including API spec documentation that can power Swagger. Then there's security, CORS, access control and other important features like pagination, filtering, validation, content-type negotiation, GraphQL... and... honestly, I could keep going.

This is why API Platform exists: to allow us to build killer APIs and love the process! Oh, and that big list of stuff I just mentioned that an API needs? API Platform comes with all of it. And it's not just for building a huge API. It really is the perfect tool, even if you only need a few endpoints to power your own JavaScript.

So let's do this! API Platform is an independent PHP library that's built on top of the Symfony components. You don't need to use it from inside a Symfony app, but, as you can see here, that's how they recommend using it, which is great for us.

If you follow their docs, they have their own API Platform distribution: a custom directory structure with a bunch of stuff: one directory for your Symfony-powered API, another for your JavaScript frontend, another for an admin frontend all wired together with Docker! Woh! It can feel a bit "big" to start with, but you get all of the features out-of-the-box... even more than I just described. If that sounds awesome, you can totally use that.

But we're going to do something different: we're going to install API Platform as a bundle into a normal, traditional Symfony app. It makes learning API Platform a bit easier. Once you're confident, for your project, you can do it this same way or jump in and use the official distribution. Like I said, it's super powerful.

Anyways, to become the API hero that we all need, you should totally code along with me by downloading the course code from this page. After you unzip it, you'll find a start/ directory inside with the same code that you see here... which is actually just a new Symfony 4.2 skeleton project: there is nothing special installed or configured yet. Follow the README.md file for the setup instructions.

The last step will be to open a terminal, move into the project and start the Symfony server with:

symfony serve -d

This uses the symfony executable - an awesome little dev tool that you can get at https://symfony.com/download. This starts a web server on port 8000 that runs in the background. Which means that we can find our browser, head to localhost:8000 and see... well, basically nothing! Just the nice welcome page you see in an empty Symfony app.

Now that we have our empty Symfony app, how can we install API Platform? Oh, it's so awesome. Find your terminal and run:

composer require api

That's it. You'll notice that this is installing something called api-platform/api-pack. If you remember from our Symfony series, a "pack" is sort of a "fake" library that helps install several thing at once.

Heck, you can see this at https://github.com/api-platform/api-pack: it's a single composer.json file that requires several libraries, like Doctrine, a CORS bundle that we'll talk about later, annotations, API Platform itself and a few parts of Symfony, like the validation system, security component and even twig, which is used to generate some really cool documentation that we'll see in a minute.

Back in the terminal, it's done! And has some details on how to get started. A few recipes also ran that gave us some config files. Before we do anything else, go back to the browser and head to https://localhost:8000/api to see... woh! We have API documentation! Well, we don't even have any API yet... so there's nothing here. But this is going to be a huge, free feature you get with API Platform: as we build our API, this page will automatically update.

Let's see that next by creating and exposing our first API Resource.

Leave a comment!

2020-05-18Vladimir Sadicov

Perfect! no problem It's great that you solved it!!!

Cheers and have a nice day!

2020-05-18Vladimir Sadicov

I guess you have wrong symfony cli installed. Did you installed it from here? https://symfony.com/download Probably you got a very outdated tool installed somehow, install one from link I gave, and try again

Cheers!

2020-05-18mike last

Hi Vladamir, I managed to fix my issue - something going wrong with docker somewhere - thanks for taking the time to help

2020-05-18mike last

server command is not defined, im on latest macOS and cli version is 1.5.11

2020-05-18Vladimir Sadicov

that sounds weird, ok what about symfony server:start? And several other questions, what OS do you use? What version of symfony cli tool? check it with symfony version command

The bin/console is a php file, so it's likely that your Windows installation is not executing such file with PHP. Try running it like this: php bin/console and let me know if it worked

Cheers!

2020-01-21José Neto

How do I install it on Windows? After the require, the bin/console is not a win executable.

2020-01-08weaverryan

Hey @MrWeksalwm!

Hmm. Try running:

composer require symfony/apache-pack

That's a fake package that will add a public/.htaccess file that's needed by Apache. I bet that's what you're missing - as Apache's rewrite rules won't work without it.

Let me know if that helps!

Cheers!

2020-01-08MrWeksalwm

I have a problem, due to doing things slightly differently than recommended in the tutorial (mea culpa). Instead of using "symfony serve", I am using Docker for my local environment. A portion of my "docker-compose.yml" looks like this:

Welcome to Symfony and ApiPlatform :)What you are experiencing is normal. The default "homepage" only works on the dev environment. You just need to create your own routes and it should work fine

Cheers!

2019-12-07Annemieke Buijs

I really really like symfony and api platform. But i have a weird challenge.(i've never installed anything on a linux machine before, so bear with me please AND i am a newbie to symfony 4).

We have a new Azure server. CentOs is the operating system on which the symfony applications are going to run.I've installed the latest php, symfony, apache, composer etc.I have created a Virtual host ,

I've tested this virtual host with an index.php in the public folder. This index.php has some links to html files in different folders.This works just fine, no problem.

Then i took the zipfile from this course and put the start project of this zipfile on the server. Just for testing purposes. See if i can get it to work.The welcome page works fine but the url /api gives a "is not found".As soon as i change APP_ENV to prod (cache:clear) the welcome page does not show up anymore, I get a 404.

Yep... this is a real challenge for open source. We try to give back (in this case to API Platform) by consulting with them (for $) on the tutorial and other ways. Hopefully everyone wins, with great screencasts and a bit more support back to the project itself.

Cheers!

2019-10-04zpine

Hello Ryan,

Sorry for the delayed reply, Thank you very much for your quick response and detailed explanation! Very impressive!

1. Yes, I tried the DTO approach by following the official documentation examples and it solved the problem. But as I mentioned before it's not easy as following your screencasts. There are so many pieces missing and official document requires lots of improvements (Can't blame anyone since it's open source project and it's our responsibility to contribute). Unfortunately I cannot contribute to documentations because of my limited English.

1. Hmm, yea, I understand much better now - thanks for the clear code and database structure :). Because you're writing to fields from multiple entities, the "cleanest" situation here is probably a DTO (https://api-platform.com/do... ... or maybe an API resource that is not an entity (those are subtly different things). If you used a DTO, it would just give you a bit of a "cleaner" way to have the extra fields and then create the underlying entities that you need. Basically, you wouldn't need to create those extra fields in the User entity because they would be on your "input" DTO. But, I may be missing a detail - because I'm not sure what you other things you're processing in the doctrine event listener.

Btw, adding an extra "setBusinessName()" method to your User entity so that you have a businessName field is not a bad solution. And you could either use a custom data persister to use that value to create the Account object. That's the classic trade-off between a DTO and adding custom fields via customer getters/setters: adding a custom getter/setter is a bit dirty, but super easy, and a nice solution if you only need to add limited fields. But if you need several more fields, a DTO becomes more attractive and keeps things cleaner.

I don't know if I fully answered your question, so let me now :).

Cheers!

2019-09-25zpine

Hi Ryan,

Thank you very much for the quick response.

1. I think my English terms are confusing..... It's difficult for me to explain without an example (English is not my native), so I have created a gist with minimal version of app entities

This form collects data of 2 different entities in a single request and after a successful signup a new User and a Account object will be created along with membership role 'ROLE_OWNER'. So to be frank with you I really don't know the proper steps to handle this but as a work around I created some extra fields on User entity and created a doctrine event listener to do the rest of the things based on logged in user. I am pretty sure there maybe a better way to handle this. (DTO or Some other technique)

> 1. Many to Many with extra fields (by only exposing one resource to the API)

Can you tell me more about this? I understand the Many to Many with extra fields part, but I'm not sure what you mean by only exposing one resource to the API part.

> 2. Working with DTOs

Yep, definitely - next course will cover this - one of my favorite "missing" features for the tutorial :).

Cheers!

2019-09-24zpine

Hi Ryan,

I have followed your "API Platform Part 2" course series and now I realize that most of the challenges I had already covered in that course. So now I agree that API Platform can be used for any type of API implementations :), thanks again for your efforts to make this course simple to understand. It would be great if you can add some more sections which covers the following:

1. Many to Many with extra fields (by only exposing one resource to the API)2. Working with DTOs

Apart from that a separate course for VueJs with Symfony would be great!

Thanks for the kind words! It especially means a lot to me because you've already worked on API Platform before :).

> 1. Is it a good idea to use API Platform for building public 3rd party interacting APIs? (e.g: Similar to SendGrid API)

I would say... yes! If you ask the API Platform team, that would of *course* say yes... and I think I agree with them. But, I'm interested about what challenges you see with using it for a public API? The fact that it exposes the JSON-LD & OpenAPI stuff makes it especially a good fit for a public API. And, from an authentication standpoint, it's really "agnostic" to how you authenticate. What I mean is, you can setup whatever authentication mechanism you want.

So, what challenges are you thinking about? I would really like to hear your thoughts :).

Cheers!

2019-09-20zpine

Hi! Thank you for this excellent course. I have worked with API Platform on several projects by referring the official documentation but it's not easy as following this course. I really love the way you explain things in plain simple English.

I have a general question: (I am sorry if it's not related to course content)

1. Is it a good idea to use API Platform for building public 3rd party interacting APIs? (e.g: Similar to SendGrid API)Personally I believe it's well suited for CRUD operations (js based front-end clients and mobile apps). When it comes to 3rd party APIs there are several challenges and I feel like using API Platform would complicate things.

2019-07-30Virginie Burlot

Hi, and thank you for your courses, I just updated my subscription back to start learning again.

But, I'm a bit frustrated by this new Symfony CLI. I can't make it work on my work computer.

I've followed all the instuction to install it, and I can't create new SF4 projects, it tells me to use composer for SF4 projects, that the Symfony CLI only works for SF2 and 3 projects..

I've followed all the steps in your README for this course, and I still can't use the Symfony CLI, when I try the "symfony serve" command, I have an InvalidArgumentException : Command "serve" is not defined.

I'm on Windows 7 here at work, and maybe the Symfony CLI don't work on this OS and won't as it's kinda old.I really don't know how to solve this, I see everywhere now, in every documentation, to use the Symfony CLI, and I'm completely stuck.

I can still use composer, as I did when I started my precedent project, but I would like so much to follow the hype train.

Edit : I just added the webserver-bundle to continue this course, it's so frustating !

Edit 2 : So, basically, I feel stupid. I had installed the old symfony.phar (dating back to SF3) in one of my PHP folder. This folder itself was in my PATH. So, the "symfony" command wasn't calling the new Symfony CLI, but the symfony.phar. Thanks to W7 horrible PATH management, I did not see it coming.

I deleted the old .phar, and everything went as expected. Gosh, I feel stupid.

There will be - but not in this part 1. We've still got a lot to do with events, data persisters, custom endpoints, etc, which will likely be covered in part 3 (after part 2, security). We're going to work to minimize the delay between the parts.

Cheers!

2019-06-24Azeem Michael

is there going to be a session on event listeners? I don't see it in the chapters. Would be helpful if people want to to some pre/post events. E.g., make a stripe api call or send email on order creation.

I have a good news. Setting environment variable NODE_TLS_REJECT_UNAUTHORIZED to 0 should fix this issue. You can set it with export NODE_TLS_REJECT_UNAUTHORIZED=0before running your command.

Hope it will help!

Cheers!

2019-06-11Victor Bocharsky

Hey Vinz,

Ah, nice! Good luck with the migration! I hope it won't be too complex. Every new version of Symfony has a lot of improvements, this will be a big step forward ;)

Cheers!

2019-06-11Vinz Stoned Orgies

Thanks Victor Bocharsky, I'm in the process of migrating to SF4.3 so it should be OK. And I always prefer to work on my own projects :)

2019-06-11Victor Bocharsky

Hey Vinz,

We always suggest our users to download the course code and code along with us from start/ directory. But of course it's not a requirement, you can follow the tutorial making changes in your own project. Well, to improve DX it would be good if your Symfony 3.4 project uses Symfony Flex, otherwise you would need to create configs and register bundles yourself. I see API platform should work on Symfony 3.4, though probably not the latest version, so if you want to go this way - I think you can try.

Cheers!

2019-06-10Steven

Hey Victor,removing and installing the ca again did the trick. I actually did the $ symfony server:ca:install several weeks ago, that must have been the problem. Seems I was a bit hasty there: the problem persists. I'm running this on debian 9.9 with symfony cli v4.5.5. I'll just use http in the meantime and wait for a fix.

Hi, is it possible to user API Platform on an existing SF3.4 project ? Or is it better do to it on SF4 ?

2019-06-10Victor Bocharsky

Hey Steven,

Hm, are you on Windows? Try to remove certs with another command:

$ symfony server:ca:uninstall

Then try upgrade your Symfony client to the latest version with:

$ symfony self:update

And reinstall the certs again:

$ symfony server:ca:install

Does it help? Did you see any errors in the output?

You can search for a similar on the Symfony Client repository: https://github.com/symfony/cli - I see there's a few opened issues about similar problem.

If the problem persist, as a workaround you can try to use HTTP instead of HTTPS in the URL.

Cheers!

2019-06-09Steven

Hey, thanks for these awesome tutorials. I have some slight problems using the new symfony executable: after setting up https by doing symfony server:ca:install i can't use the api-platform client-generator in my local environment due to the self-signed certificate:

Can you show me the full message? Also, what Symfony CLI version do you have?

Cheers!

2019-06-03Jérôme 

I have a question for you... Maybe it's a silly question, but I'd really like to know. I've been seeing everywhere people using the Symfony CLI to make projects, but I still use composer to do it. For example, in this tutorial, you've used "symfony serve -d"... But when I tried to use the SF CLI, a message tells me to use composer, so I'm a little bit confused. Am I doing something wrong, or did I miss something? I'm curious... Thank you!