I have recently started looking at using a PHP microframework to build a simple REST API for an app I’m working on. I was looking for something well supported/documented which would be easy to integrate with Doctrine 2. I’d heard good things about Slim 2 so thought I would check out the new version and maybe write a bit about it.
To jump straight to my final code you can checkout the example here.
Akrabat has already created a Slim 3 Skeleton App so I decided to use that as my starting point. As a bonus it comes with Twig and Monolog setup and ready to go too. Once you have created a new project using the skeleton app you can install Doctrine 2.
That will install doctrine 2 and its dependencies.
Inside the app/settings.php file append your Doctrine 2 configuration and adjust the connection details to your own settings.
Command Line Tools
Doctrine 2 has comes with various command line tools that are quite helpful during development. To use these we create a cli-config.php file which will register the EntityManager with the console. This file should live in the root directory of our app but as of Doctrine 2.4 it can be in a sub directory called config. The content of my config file is below.
You can now see what tools are available by running this command.
Two commands I use a lot during development are
These tools are only really for development use though and should not be run on a live production server for obvious reasons. I ran the create command to generate the necessary tables based on my entities in the entity path. For the purpose of this demo I just have the one below.
If you are wondering why I specified a character length on my columns it’s because I am using MySQL.
I’ll leave it to you to add some dummy records into the table :)
Now that we have Doctrine 2 configured and access to the command line tools we can start to integrate it to our app. The first step is to setup a service container for Doctrine 2 EntityManager in the app/dependencies.php file.
Slim 3 ships by default with a DI container that extends Pimple which I think is fine for the basic needs on my project. However, I have read over the last few months Shameer C, Julian Gut and Akrabat have been eager to replace this with their own choice of DI container. You should read about why in the links above. Make your own choice :)
Establish some routes
My basic API needed to do two things intially - return a list of photo resources and a single photo resource based on a slug.
Am I done yet?
Well very nearly. At this point I could just have injected the EntityManager direct into my controller similar to how Twig and Monolog are in the skeleton app examples…
…and then requested photos directly from inside the controller.
Although this works fine, I and many others would generally advise against this approach.
It is not good practice to fetch data through accessing the EntityManager directly in a controller. Controllers should be skinny and that type of application logic should be called through services. Since I am developing a REST API I abstracted this code out into separate resource classes. After all the nature of a REST architecture is that everything is a resource.
I took inspiration from A.Sharif who follows this approach in his post on integrating Doctrine 2 and Slim version 2. After having already written this post I then came across the Slim REST API (Slim 2) which goes one step further and abstracts out the relevant code to interact with EntityManager into a related service class which removes the dependency on EntityManager from the resource class.
To save time injecting the EntityManager into each resource I make I made an abstract resource class app/AbstractResource.php with the following contents. Each resource I make from now on can extend this class.
Below is my resource class for photo which extends the abstract resource.
Below is the controller I have to access photos. All it does it interact with the resource to get data and return a JSON response.
Given these changes I now update my action factory for the Photo controller in the dependencies like so.
Now I’m done
Well like most good developer blog posts I’ve finished before actually getting started. You can view my example here. It’s up to you now to go off and carry on building your lightweight Slim 3 app using Doctrine 2. I’m off to pick some fresh tea leaves.