Recently, developers of all modern applications aim to prepare applications based on REST APIs which are usually consumed by client-side applications.

Such an approach simplifies reusing code, testing application and improve scalability.

I will show you how to prepare application based on REST API in a few steps using API Platform – Framework written in PHP for building REST APIs.

I assume that you know what REST API is, so I will not explain it here. If you want to refresh your knowledge, I encourage you to take a look at this article.

First, what API Platform is? The author says ‘API Platform is a powerful and easy to use full stack framework dedicated to API-driven projects’, so I guess we are supposed to be able to prepare full application in short amount of time… We will see.

For this tutorial we are creating a small API service for managing accounts and roles.

Project requirements:

  1. Create accounts
  2. Create roles
  3. Add roles to account
  4. Filter active accounts
  5. Paginate lists

Versions

API Platform – v2.2.7

Docker – 18.03.1-ce, build 9ee9f40

Docker-Compose – 1.19.0, build 9e633ef

OS – Ubuntu 16.04.4 LTS

Installation

  1. Download the release https://github.com/api-platform/api-platform/releases/tag/v2.2.7
  2. Install Docker and Docker-Compose
  3. Run all containers in detached mode. It will take a few minutes. Important! If a service works on your machine (Apache, Nginx etc.) which blocks port 80, then stop this service for this tutorial.

4. After running the following command, you should see containers for Nginx, database (PostgreSQL), cache layer and so on.

5. See already working app http://localhost:8080

REST APIs

Now we can start implementing our application.

Implementation

  • Create Account entity

First, we have to remove the class example/api/src/Entity/Greeting.php

Next we have to install doctrine maker recipe to use make:entity command

Now we can run command make:entity to create Account class.

API Platform

After filling out entity creator fields, we have something like this at the end:

# example/api/src/Entity/Account.php

 

Please take a look at ApiResource annotation in DOC class comment. Thanks to this now we are able to run REST CRUD commands via Swagger Sandbox http://localhost:8080 or some other HTTP Client

You can run the command to check your application routes:

As you can see some new routes appear:

  • Database setup

Our API does not work because we have to initialize our database.

Let’s run commands to create migration:

Now we have to prepare some data for testing.

We will use fixtures to load ‘fake’ data to the database.

To be able to load fixtures we have to install orm-fixtures recipe

Here are some prepared fixtures, they will be enough for tutorial’s purposes:

# example/api/src/DataFixtures/AccountFixtures.php

 

Now we can run the mentioned below command to load data to database:

Now our endpoints work correctly.

  • Data format configuration

We can get data in three formats by default: application/json, application/ld+json and text/html.

We can negotiate content format by setting up header Content-Type.

I have added one more (my favourite) format application/hal+json which is common JSON, but with hypermedia like pagination info and so on.

 

example/api/config/packages/api_platform.yaml

 

You can compare response formats mentioned below:

 

JSON

JSON-LD

JSON-HAL

It is up to you which one you choose.

 

  • Validation

Validation is performed in ValidateListener, so if you add Constraint annotations to your model like here:

example/api/src/Entity/Account.php

 

API Platform will do everything for you: perform validation and return prepared response with message and proper HTTP error code in case of error.

 

  • Pagination

For performance purposes, API Platform has enabled pagination by default for all resources, but we can configure it globally and by resource too.

To see how it works we need to change a little bit AccountFixtures.php file to load more than one record.

# example/api/src/DataFixtures/AccountFixtures.php

 

Load new data to database:

Go to http://localhost:8080 and take a look at Parameters section in GET endpoint of /accounts resource

Below, I set default records to 10 per page (default is 30) and I enabled ability to set amount per page by client via setting up itemPerPage query parameter.

# example/api/config/packages/api_platform.yaml

 

Now we are able to decide how many records we will get. Check out itemPerPage parameter in Parameters section.

 

  • Filters

We can enable filtering in a very convenient way, I will show you how to filter only active accounts.

First, we have to add isActive property to our Account.php. Note that we can use make:entity command to add new properties to an existing class.

# example/api/src/Entity/Account.php

 

Run in your terminal:

We have to change AccountFixtures.php to set various isActive values for accounts

# example/api/src/DataFixtures/AccountFixtures.php

 

Run the following command in your terminal:

We have to add ApiFilter annotation to our model Account.php

# example/api/src/Entity/Account.php

 

Now we can see something like dropdown isActive in Parameters section:

And as a result we can set up a filter in our sandbox or add ?isActive=true query parameter to the URL in HTTP Client:

Summary

We went through some basic functionality of API Platform. As you can see it was easy to configure functionalities like pagination and filtering via some annotations. Thanks to Docker we were able to run application without any complicated environment configuration. The beginning of this tutorial could be done on one entity example/api/src/Entity/Account.php but next time we will talk about more advanced features like Subresources, Normalization/Denormalization and Nested Objects, so then we will prepare example/api/src/Entity/Role.php entity and create relation between both entities.

Bonus

  • Full example

https://github.com/slawomirkania/example

Run following commands to start the application:

If you have any problems with php container, check error by running command:

Resolve problems and then try again.

slawomir.kania

Software Engineer experienced in REST and Microservices solutions. Interested in modern web technologies.