In this video we are going to implement the collection GET - or cgetAction.

This is very similar to the getAction we implemented in the previous video, only this time we will return an array of BlogPosts, rather than an individual item.

To give you a more visual idea of what this means, consider this:

{
    "id": 36,
    "title": "a blog post title here",
    "body": "a blog post body here"
}

This would be a single BlogPost, represented as JSON, and returned from a call to:

http://api.symfony-3.dev/app_dev.php/posts/36

Now, with a collection, we would get multiple 'copies' of this same structure, only with different data, and wrapped in the JSON array syntax - []:

http://api.symfony-3.dev/app_dev.php/posts

returns:

[{
    "id": 1,
    "title": "first post title",
    "body": "first post body"
},
{
    "id": 2,
    "title": "second post title",
    "body": "second post body"
}]

And so on.

The important thing is that the shape of the data is the same - unless you start playing with serialization groups.

To quickly summarise, when your object / entity is converted (serialized) from PHP to JSON, you can use annotations such as:

     * @Annotations\View(serializerGroups={
     *     "accounts_all",
     *     "users_summary"
     * })

To alter what fields are included or excluded from the JSON output. This is cool, and powerful, but be careful as this can also make your API code more difficult to maintain. An example of this problem will occur a little later in the series when we implement PUT functionality in the browser / front end code.

Pre-empting Pagination

For the moment we aren't implementing any pagination, filtering, or sorting. But this will be needed a little later on.

As covered in the previous video, it therefore makes sense to work with this in mind, and structure out querying accordingly. Therefore, our entity repository is going to return queries rather than results:

<?php

// /src/AppBundle/Entity/Repository/BlogPostRepository.php

namespace AppBundle\Entity\Repository;

use Doctrine\ORM\EntityRepository;

class BlogPostRepository extends EntityRepository
{
    public function createFindAllQuery()
    {
        return $this->_em->createQuery(
            "
            SELECT bp
            FROM AppBundle:BlogPost bp
            "
        );
    }

Which means in our controller action we do need to explicitly call the getResult method:

// /src/AppBundle/Controller/BlogPostsController.php

    public function cgetAction()
    {
        return $this->getBlogPostRepository()->createFindAllQuery()->getResult();
    }

Because both getAction and cgetAction need to access the repository, I have extracted the duplicated code to a private method:

// /src/AppBundle/Controller/BlogPostsController.php

    /**
     * @return BlogPostRepository
     */
    private function getBlogPostRepository()
    {
        return $this->get('crv.doctrine_entity_repository.blog_post');
    }

If unsure on this, we declared the service in the previous video.

Later on in this series, we will be able to pass the as-yet-unrun query into the paginator, which will add in the necessary offset and limits to return the requested results. This stops a potential problem whereby we might have always run a SELECT * FROM blah type query, and then sliced and diced the result. This would be one of those problems that likely didn't show itself in development, when we have say 50 records in our DB, but with 100,000 in production, suddenly the entire system crawls to a halt.

And that's largely it for the moment with regards to GET'ting a collection of BlogPosts. As ever with programming, all the hard work happens at front, and then the implementation is almost a formality.

Of course, changes will need to be made, and that is almost inevitable on any project, but for the moment this is good enough.

Code For This Episode

Get the code for this episode.

Share This Episode

If you have found this video helpful, please consider sharing. I really appreciate it.


Episodes in this series

# Title Duration
1 Intro with Twig CRUD - List 06:03
2 Twig CRUD - Create 03:25
3 Twig CRUD - Update (Edit) 02:43
4 Twig CRUD - Delete 02:36
5 Simple Symfony 3 RESTful API Setup 05:32
6 API - GET a Single BlogPost 04:51
7 API - GET a Collection of BlogPosts 02:20
8 API - POST to Create New Data 06:30
9 API - PUT and PATCH to Update 04:11
10 API - DELETE 03:34
11 Angular - Setup, Styling, and GET All 09:19
12 Angular - Refactoring 10:23
13 Angular - Create (POST) 06:54
14 Angular - Update (PUT) 08:41
15 Angular - Remove (DELETE) 06:44
16 React - Intro, Setup, and GET all 06:54
17 React - Refactoring 09:14
18 React Router 04:41
19 React - Create (POST) 13:13
20 React - Update (PUT / PATCH) 12:40
21 React - Delete 11:00
22 React - Tidy Up, and Finish 04:14