Introducing the API Platform [API Platform]


We've previously covered how to create a 'RESTful' API (more accurately a JSON API) using Symfony 4. We've covered how to create a Symfony 4 JSON API with as few extra dependencies as possible, and also a separate build using FOSRESTBundle. Now, let's take a look at recreating our Album API using the API Platform.

If you haven't heard of API Platform before I genuinely think your socks are about to be knocked clean off.

Out of the box, this is the most fully featured API I have ever found in any programming language.

We get:

  • Either a Hypermedia or GraphQL API
  • A full React-based admin panel
  • Lovely autogenerated Open API (previously called Swagger) documentation
  • React, Vue, or React Native front end generators
  • A ready-to-go Docker stack

This barely scratches the surface of what's in there. And this isn't meant to be a sales pitch. But I would be amazed if you aren't about to be impressed.

Is there a downside?

Yes - there is one. This is just my opinion.

This doesn't work like most every other Symfony site I've ever built. This won't be like FOSRESTBundle. We won't be working with forms, building our own controllers, defining routes, or most anything you'd do typically.

We won't be using MVC.

The API Platform uses Action Domain Responder (ADR) instead.

You can still do all the usual Symfony 'stuff'. This is a Symfony-based project, after all. But there are new ways of working here. Ultimately this means there is an additional learning curve.

Is API Platform The Official Symfony 4 API Standard?

Before proceeding it's worth quickly covering whether the API Platform is now the officially recommended way to make an API with Symfony 4.

Please note that I do not have a definitive answer on this. However, the results from the Symfony Recipes Server are interesting:

symfony-recommended-api-recipe-server

The api-platform/api-pack is tagged 'Official'.

Somewhat strangely, FOSRESTBundle doesn't come up for a search on the keyword of 'api'.

This is because the search facility - at the time of writing - only considers the Recipe title. With 'api' not being in friendsofsymfony/rest-bundle, the search facility misses this - reducing discover-ability.

Even when we do find friendsofsymfony/rest-bundle, the recipe is marked as contrib (or third party, to you and me).

From an outsiders perspective it does appear that API Platform is the officially recommended approach for making an API with Symfony 4.

This said, I love FOSRESTBundle. I use it here on CodeReviewVideos.com, as well as on a bunch of other sites. It's still actively maintained and feature full, and potentially a great fit for your needs.

As ever, use your best judgment, and be grateful for the variety of options.

Getting Setup

To work with API Platform most easily, you will need Docker and Docker Compose.

If you are new to Docker, please watch my Docker Tutorial for Beginners. Everything you will need to know is covered in that course.

Compared with both the 'basic' Symfony 4 JSON API, and the Symfony 4 with FOSRESTBundle API implementations, getting setup here is an absolute breeze.

Head over to the Download page.

I'll be working with API Platform 2.2.6, at the time of recording. Please note, if using a later version of API Platform, things may be different. For best compatibility with this tutorial, please stick to ~2.2.6.

wget https://github.com/api-platform/api-platform/archive/v2.2.6.tar.gz
tar -zxvf v2.2.6.tar.gz

In other words, download the file and extract it to somewhere on your machine.

Next, bring the API Platform up and online:

cd api-platform-2.2.6
docker-compose up -d

Your terminal will fill up with a bunch of output. And this process may take a while, particularly if on a slow Internet connection.

Heads Up: Got Postgres up and running on your machine already? For simplicity, stop your local Postgres instance. If feeling daring, change the exposed public port in docker-compose.yml to something other than 5432. Don't forget to update your api/.env file!

Hey guess what? We're done.

Go ahead and open https://localhost in your browser. Accept the security warning (or just browse to the http version instead):

symfony-4-api-platform-tutorial

I'm sure I don't need to encourage you to have a play around with all this new functionality.

We'll get on to our own implementation next.

Shutting Down

Because we ran Docker in detached mode (docker-compose up -d) it's really easy to forget you've got a full stack of 'stuff' up and running in the background.

Don't forget to run docker-compose down when finished.

This will safely stop and remove the running API Platform Docker containers. You must run this command from the project root directory.

Personally I like to create either a system-wide alias for this command, or a local Makefile with my most frequently used commands in there:

# Makefile

dev:
    @docker-compose down && \
        docker-compose \
            -f docker-compose.yaml \
        up -d --remove-orphans

down:
    @docker-compose down

This means I can run the make dev command to bring my environment up, and restart it with the same command. And I can shut down with make down.

When working with environment variables in particular, it can be handy to easily restart your entire stack without having to type a bunch of stuff. Hey, it works for me.

Episodes

# Title Duration
1 What will our JSON API actually do? 08:46
2 What needs to be in our Database for our Tests to work? 12:32
3 Cleaning up after each Test Run 02:40
4 Docker makes for Easy Databases 09:01
5 Healthcheck [Raw Symfony 4] 07:53
6 Send in JSON data using POST [Raw Symfony 4] 05:33
7 Keep your data nice and tidy using Symfony's Form [Raw Symfony 4] 10:48
8 Validating incoming JSON [Raw Symfony 4] 08:26
9 Nicer error messages [Raw Symfony 4] 06:23
10 GET'ting data from our Symfony 4 API [Raw Symfony 4] 08:11
11 GET'ting a collection of Albums [Raw Symfony 4] 01:50
12 Update existing Albums with PUT [Raw Symfony 4] 05:00
13 Upsetting Purists with PATCH [Raw Symfony 4] 02:39
14 Hitting DELETE [Raw Symfony 4] 02:11
15 How to open your API to the outside world with CORS [Raw Symfony 4] 07:48
16 Getting Setup with Symfony 4 and FOSRESTBundle [FOSRESTBundle] 09:11
17 Healthcheck [FOSRESTBundle] 06:14
18 Handling POST requests [FOSRESTBundle] 08:31
19 Saving POST data to the database [FOSRESTBundle] 09:44
20 Work with XML, or JSON, or Both [FOSRESTBundle] 04:31
21 Going far, then Too Far with the ViewResponseListener [FOSRESTBundle] 03:19
22 GET'ting data from your Symfony 4 API [FOSRESTBundle] 05:58
23 GET'ting a Collection of data from your Symfony 4 API [FOSRESTBundle] 01:27
24 Updating with PUT [FOSRESTBundle] 02:58
25 Partially Updating with PATCH [FOSRESTBundle] 02:15
26 DELETE'ing Albums [FOSRESTBundle] 01:27
27 Handling Errors [FOSRESTBundle] 08:58
28 Introducing the API Platform [API Platform] 08:19
29 The Entry Point [API Platform] 04:30
30 The Context [API Platform] 05:52
31 Healthcheck - Custom Endpoint [API Platform] 05:17
32 Starting with POST [API Platform] 07:08
33 Creating Entities with the Schema Generator [API Platform] 07:38
34 Defining A Custom POST Route [API Platform] 07:31
35 Finishing POST [API Platform] 06:29
36 GET'ting One Resource [API Platform] 02:50
37 GET'ting Multiple Resources [API Platform] 02:59
38 PUT to Update Existing Data [API Platform] 02:19
39 DELETE to Remove Data [API Platform] 01:15
40 No One Likes Errors [API Platform] 03:28