Simple Symfony 3 RESTful API Setup

In this video we are going to cover all the setup and configuration changes required to start using our Symfony 3 installation as a RESTful API. To achieve this we will make use of a number of third party bundles:

  • FOS REST Bundle
  • JMS Serializer Bundle
  • Nelmio CORS Bundle
  • Nelmio API Doc Bundle

And we will continue to include Will Durand's Faker Bundle.

If you'd rather just see the code directly, you can do so by visiting the GitHub Repo.

Some points to note here:

We are going to use FOS REST Bundle at version 1.7. There are many changes coming shortly in version 2.0, but this is still under active development. I have opted to keep with a stable version for this project, but would recommend trying 2.0 if you are not building a 'serious' project. There are many fixes that make life that little bit easier for you.

The relevant part of the composer.json file would be :

    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.1.*",
        "doctrine/orm": "^2.5",
        "doctrine/doctrine-bundle": "^1.6",
        "doctrine/doctrine-cache-bundle": "^1.2",
        "symfony/swiftmailer-bundle": "^2.3",
        "symfony/monolog-bundle": "^2.8",
        "symfony/polyfill-apcu": "^1.0",
        "sensio/distribution-bundle": "^5.0",
        "sensio/framework-extra-bundle": "^3.0.2",
        "incenteev/composer-parameter-handler": "^2.0",

        "nelmio/cors-bundle": "^1.4",
        "nelmio/api-doc-bundle": "^2.11",
        "friendsofsymfony/rest-bundle": "^1.7",
        "jms/serializer-bundle": "^1.1",
        "willdurand/faker-bundle": "^1.3"

If you would rather go with the later version of FOS REST Bundle, update accordingly:

"friendsofsymfony/rest-bundle": "^2.0@dev",

By using the @dev tag you can avoid having to change your entire project's stability setting. I blogged a little more about updating here.

We're making use of JMS Serializer to enable - unsurprisingly - serialisation and deserialisation in our project. This is how we can easily transform JSON into PHP / Symfony-friendly entities, and back again.

Nelmio CORS bundle enables us to easily configure Cross-Origin Resource Sharing headers, which will make communicating with our API from our front end much simpler.

Lastly, Nelmio API Docs bundle is a little uncertain at this point. There was mention of the bundle being deprecated by its maintainer - Will Durand. Judging from the reaction to the Twitter poll, it seems its future is secure in the short term, but this is something to be aware of in the longer term. I currently don't have an alternative to this, but if you know of one, please do leave a comment below.

The config for all these bundles is as follows:

// /app/AppKernel.php
class AppKernel extends Kernel
    public function registerBundles()
        // * snip *

        new FOS\RestBundle\FOSRestBundle(),
        new Nelmio\CorsBundle\NelmioCorsBundle(),
        new Nelmio\ApiDocBundle\NelmioApiDocBundle(),
        new JMS\SerializerBundle\JMSSerializerBundle(),


# /app/config/config.yml

# Nelmio CORS
        allow_origin:  ["%cors_allow_origin%"]
        allow_methods: ["POST", "PUT", "GET", "DELETE", "OPTIONS"]
        allow_headers: ["content-type", "authorization"]
        max_age:       3600
        '^/': ~

# Nelmio API Doc
        accept_type:        "application/json"
            formats:        [ "json" ]
            default_format: "json"
                json:       "application/json"

# FOS REST Bundle
    body_listener: true
    param_fetcher_listener: true
        view_response_listener: 'force'
        exception_wrapper_handler:  null
            jsonp: true
            json: true
            xml: false
            rss: false
            json: ['application/json', 'application/x-json']
            jpg: 'image/jpeg'
            png: 'image/png'
        jsonp_handler: ~
        default_format:  json
        include_format:  false
            - { path: ^/, priorities: [ json, jsonp ], fallback_format: ~, prefer_extension: true }
        enabled: true

Again, note this blog post if using FOS REST Bundle 2.0. There are some config changes to follow.

You should also update your parameters.yml.dist and parameters.yml files accordingly:

# /app/config/parameters.yml.dist

    # nelmio cors
    cors_allow_origin: 'http://localhost'

    # nelmio api docs
    api_name: 'Your API name'
    api_description: 'The full description of your API'

We will need to configure routing:

# /app/config/routing.yml

    resource: "@NelmioApiDocBundle/Resources/config/routing.yml"
    prefix: "/doc"

    type: rest
    resource: "routing_api.yml"


# /app/config/routing_api.yml

    type: rest
    resource: AppBundle\Controller\BlogPostsController

Lastly, I've updated the security setup to make this a free-for-all. Again, this is for simplicity, and you should of course, change this as required to suit your needs.

# /app/config/security.yml


            memory: ~

        # disables authentication for assets and the profiler, adapt it according to your needs
            pattern: ^/(_(profiler|wdt)|css|images|js)/
            security: false

            pattern: ^/doc
            anonymous: true

        - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/doc,   roles: IS_AUTHENTICATED_ANONYMOUSLY }
        - { path: ^/,      roles: IS_AUTHENTICATED_ANONYMOUSLY }

Seeding Your Database

Back in the very first video we covered how to use Will Durand's Faker Bundle to populate our database with 50 fake entities.

In this and the remaining videos, we are re-using this database, even though this is now a separate project.

If you haven't been following along since the first video, but want to seed your database similarly, be sure to add in the relevant config:


    orm: doctrine
            number: 50

And then run the needed command:

php bin/console faker:populate

That's all the boilerplate out of the way.

In the next video we will start implementing the various API endpoints to make this whole thing come together.

Code For This Video

Get the code for this video.