In this article I will describe a nice and easy way to implement a REST API with the Symfony framework.

What is a REST API?

REST API is a web service which uses REST architecture.

REST = "REpresentational State Transfer"API = "APplication Interface"

REST architecture is resource based which means that it is focused on resources instead on actions meaning that it calls (in URI) a resource (in this tutorial the resource is 'type') and uses http verb (method) to say what operation it wishes to do on the resource.

Rest typically runs over http and has several architectural constraints:

Decouples consumers from producers

Stateless existence

Able to leverage a cache

Leverages a layered system

Leverages a uniform interface

1. Install dependencies

If you don't have an existing Symfony2 project, you can see here how to create it.

A good practice in programing world is not to reinvent the wheel in each project. - Reuse the code. If there is a good code (package) that meets our needs, we should use it. In this project I've used a cool bundle: FOSRest bundle (and 2 more) to help me build REST API.

2. Create database

You need to set the database parameters in app/config/parameters.yaml, or you can run composer install command to generate the file automatically. In any case, you must provide necessary database parameters.

3. Let's create our entity

For the purpose of this article, I will present the Type entity and make REST API for it. It is linked with other entities, but they won't be displayed here because complete process of making the Type entity an API can be applied on any other entity.

So what does this method do? It fetches the entity by ID from the repository (database). If the entity is not found, NotFoundHttpException is thrown. (We will talk about exceptions later in this text) And if the entity is found, it is returned, and FOSRest bundle will convert it automatically in requested format.

If HTTP PUT method is called, we should search the database for the entity by the given ID.

If we find the entity, we apply the request data to it, validate it and persist it if valid. If the data is invalid, an exception is thrown. All that, except the search, is done within processForm method, which is presented in the text above.

If the entity doesn't exist in the database, it's being created, validated and persisted just like the POST method is called.

As you can see, first we get the entity and then we 'patch' it - update some of it's fields. There lies the main difference between PUT and PATCH HTTP methods - PATCH updates only the fields which were submitted in the request data, and other fields stay unchanged. While PUT updates all the fields of the entity. If some fields are omitted in the request data, those fields will be set to NULL in the entity. Also, PUT method can create new entity while PATCH can't.

7. Exceptions

Good handling of exceptions is important because they help you in development by giving you precious feedback, and they show an error to a user if it occurs. FOSRest bundle catches the exceptions thrown from the controller actions and makes http error messages which are returned to the user.

Important!

There is difference in FOSRest bundle behaviour in development and production environments. In development environment, complete error messages from all uncaught exceptions are sent to the user (developer), while in production, only http error codes with their message are sent to the user. For example if there is some database error caused by invalid user data, FOSRest bundle will return http code 500 with error message: 'Internal server error', which is good. In that way sensitive internal information about the system (which might be contained within e.g. database error message) is being protected. But, if the developer wishes to give more descriptive message to the users, then he must register an exception class and associate it with a http error code. Then he will be able to set a custom error message with more details about the error, and yet he will have control over system data which is being presented to the user.

All custom exceptions must be registered in config.yaml file, what you can see in The routes and the configuration section of this article.

All exceptions thrown by the system (e.g. doctrine) must be catched, and the useful information must be extracted and presented to the client in a suitable message. That is the job of the throwFosrestSupportedException function which is called from catch blocks of my code. In this example, the function doesn't do anything smart, it just transmits the error message to the BadRequestDataException which is registered in FOSRest bundle configuration and has assigned http error code. So this function lacks the code which should parse the exception and adapt the message for the client.

On our git repository you can see complete code used in this tutorial. Cheers! :)

Contact us!

We are a digital agency specialized in the development of digital products. Our head office is in Munich/Unterföhring - but we work remotely worldwide. Our specialities are websites and portals with TYPO3, e-commerce projects with shopware and iOS and Android apps. In addition, we are also familiar with many other topics in these areas. Contact us in your preferred way: Whether by contact form, e-mail, telephone or in a Whatsapp message.

Please contact us

You have an interesting project idea, would like to engage our agency for your TYPO3 / Shopware or Symfony project or contact us about another topic? We look forward to receiving your enquiry via our form or via one of the other contact channels.

Your Name
*

Your E-mail Address
*

Your Telephone Number

Your Message
*

I have taken note of the Privacy Policy and agree with the use of my data described there.
*