Add Querying and Pagination to a CRUD RESTful API in PHP with API Platform and Symfony 4
Time to read: 4 minutes
Now that we have created a simple CRUD API, let's learn how to retrieve the data we want using query parameters, customize the pagination of the results, then create custom controllers and endpoints.
NOTE: This tutorial is Part 2 of a 2-part series. If you haven't completed Part 1, it is available here.
Adding Custom Operations to Your Endpoints
API platform automatically creates CRUD operations when the resource is created. Custom operations can be assigned to specific routes if an operation is specified. There are two types of operations for collections and items. Collection operations are operations that act on a group of resources such as retrieving all bucket lists. Item operations are operations that act on a single resource such as retrieving one bucket list. For collection operations, the GET
and POST
routes are implemented with the GET
operation being enabled by default. In item operations, the GET
, PUT
, and DELETE
routes are defined with the GET route enabled by default. In order to specify the default collection and items operations, add the following annotation before the class definition and refresh your browser. This change will take place in api/src/Entity/BucketList.php
.
Note: This can also be done using XML or YAML.
Your routes should now appear as shown below:
This will make the resource ReadOnly. If you want to add the POST
endpoint on the collectionOperations, change the collectionOperations
to collectionOperations={"get", "post"}
. The same can also be applied to the itemOperations to enable the PUT
and DELETE
endpoints.
Both item and collection operations work independently. This means that if the collection operations are configured and the item operations are not, the GET
, PUT
, and DELETE
operations will be automatically configured and vice versa. For instance, add the following piece of code:
You should expect to see all the item operations enabled by default as shown in the image below:
Adding Custom URLs
API Platform also enables adding custom URLs to your routes and overriding the default ones. In order to do that, add the following piece of code.
After refreshing your browser, the resulting screen should be similar to:
Adding a Custom Controller to Modify Endpoint Behavior
API Platform uses Symfony's routing system to register custom operations and controllers. We'll need to first create the controller at api/src/Controller/CustomController.php
.
Add the following code snippet in this file.
Next, we need to create an Entity that will use the custom controller. Create the file api/src/Entity/BucketListItems.php
and add the following code.
To generate the new models in the database, run the following command run docker-compose exec php bin/console doctrine:schema:update --force
.
Once you refresh your browser, you should see the resulting screen below.
Hit the Try out
button and click Execute
. You should expect to see the screen below.
You can add more logic to the custom controller to suit your business needs.
Enabling Pagination for Resources
API Platform enables pagination by default with each collection containing 30 items per page. The example below shows a bucket list with thirty (30) items inside. Navigating to the GET /bucket_lists
endpoint reveals only thirty items on the first page. The extra items are to be displayed on the next page.
API platform displays the total items available in your database and other page routes that have been created automatically. Enter the page number under The collection page number
, then click Execute
to navigate to the next page.
There are some instances where pagination should be disabled, such as having too few items to display. In these instances add the following lines of code to api/config/packages/api_platform.yaml
.
The input box for specifying the collection page number will be disabled and the resulting screen will appear as below when the Execute
button is clicked.
Pagination can also be disabled for a resource by adding the following annotation in the related entity class.
Changing the number of items per page can be made globally or for a specific resource. Add the following annotation in your resource and refresh your browser to change the number of items per page.
Add the following piece of code in api/config/packages/api_platform.yaml
to globally modify pagination for all resources.
The resulting pagination results will be as shown below:
Implement Search Queries in the GET endpoints
It's not necessary to write custom endpoints for filtering as API Platform provides support out of the box. If we want to filter by name in our API for example, add the following annotation and refresh your browser.
As you can see above, all bucket lists with the name Sky Diving
are returned in the response. Responses can be further customized by combining filters. Simply add the property name of the second filter. i.e @ApiFilter(SearchFilter::class, properties={"name": "exact", "description": "exact"})
.
The resulting, filtered set will be as follows:
Note the URL: http://localhost:8081/bucket_lists?name=Sky%20Diving&description=Sky%20dive%20in%20Dubai%20with%20Keisha
The query parameters are automatically appended. The SearchFilter class supports a number of filter strategies such as:
partial
searches for fields containing the text you will provide on the API client. It uses the MYSQLLIKE %searchText%
operator.start
searches for fields that start with the text you will provide on the API client. It uses the MYSQL LIKE searchText% operator.end
searches for fields that end with the text you will provide on the API client. It uses the MYSQLLIKE %searchText
operator.word_start
searched for fields containing words that start with the text provided. It uses the MYSQLLIKE text%
ORLIKE % text%
operator.
Summary
In this tutorial, we have learned how to add custom operations and URLs on the resource we created, pagination, and filters to our search queries. If you would like to dive deep into more API platform features you can have a look at their documentation page. As always, I would love to hear from you! You can reach me on Twitter or LinkedIn. Happy hacking!
Related Posts
Related Resources
Twilio Docs
From APIs to SDKs to sample apps
API reference documentation, SDKs, helper libraries, quickstarts, and tutorials for your language and platform.
Resource Center
The latest ebooks, industry reports, and webinars
Learn from customer engagement experts to improve your own communication.
Ahoy
Twilio's developer community hub
Best practices, code samples, and inspiration to build communications and digital engagement experiences.