Symfony - Api-Platform framework: получить все элементы пользователя

Я молодой разработчик, и недавно я открыл для себя Api-Platform, чтобы сделать API полноценного отдыха.

В настоящее время я слежу за документом, но не понимаю, как получить все книги человека на собственном примере.

А вот и я:

У меня есть автоматически сгенерированные сущности Book и Person, я просто добавляю между ними отношение ManyToMany.

Тогда у меня есть следующие результаты:

ПОЛУЧИТЬ api.platform.dev/app_dev.php/

{
    @context: "/app_dev.php/contexts/Entrypoint",
    @id: "/app_dev.php/",
    @type: "Entrypoint",
    person: "/app_dev.php/people",
    book: "/app_dev.php/books"
}

ПОЛУЧИТЬ api.platform.dev/app_dev.php/people/3

{
    @context: "/app_dev.php/contexts/Person",
    @id: "/app_dev.php/people/3",
    @type: "http://schema.org/Person",
    birthDate: null,
    description: "test",
    gender: "Femme",
    name: "test",
    url: null,
    books: [
        "/app_dev.php/books/1",
        "/app_dev.php/books/4"
    ]
}

Вот мои вопросы: как я могу получить во втором результате гипермедиа для всех книг человека и как лучше всего получить все книги человека?

Я начал с создания собственной операции:

#services.yml
resource.person.item_operation.custom_get:
    class:   "Dunglas\ApiBundle\Api\Operation\Operation"
    public:  false
    factory:
        - "@api.operation_factory"
        - "createItemOperation"
    arguments:
        - "@resource.person"                  # Resource
        - ["GET"]                             # Methods
        - "/people/{id}/books"                # Path
        - "AppBundle:Person:custom"           # Controller
        - "my_custom_route2"                  # Route name
        - # Context (will be present in Hydra documentation)
            "@type":       "hydra:Operation"
            "hydra:title": "A custom operation"
            "returns":     "xmls:string"

а также

// PersonController.php
<?php

namespace AppBundle\Controller;

use Dunglas\ApiBundle\Controller\ResourceController;
use Symfony\Component\HttpFoundation\Request;

class PersonController extends ResourceController
{
    public function customAction(Request $request, $id)
    {
        return parent::getAction($request, $id);
    }
}

результат на GET api.platform.dev/app_dev.php/people/3/books такой же, как у базового api.platform.dev/app_dev.php/people/3, обычно я вызываю родительский.

Но теперь, как лучше всего иметь что-то вроде этого:

# GET api.platform.dev/app_dev.php/people/3/books
{
    @context: "/app_dev.php/contexts/Book",
    @id: "/app_dev.php/people/3/books",
    @type: "hydra:PagedCollection",
    hydra:totalItems: 2,
    hydra:itemsPerPage: 30,
    hydra:firstPage: "/app_dev.php/people/3/books",
    hydra:lastPage: "/app_dev.php/people/3/books",
    hydra:member: [
        {
            @id: "/app_dev.php/books/1",
            @type: "http://schema.org/Book",
            illustrator: [ ],
            isbn: null,
            numberOfPages: 1230,
            author: [ ],
            datePublished: null,
            description: "Desription",
            genre: null,
            name: "someone",
            publisher: null
        },
        {
            @id: "/app_dev.php/books/2",
            @type: "http://schema.org/Book",
            illustrator: [ ],
            isbn: null,
            numberOfPages: 1230,
            author: [ ],
            datePublished: null,
            description: "Desription",
            genre: null,
            name: "someone",
            publisher: null
        }
    ]
}

И когда я получу api.platform.dev/app_dev.php/people/3, добавлю этот IRI /app_dev.php/people/3/books

Спасибо за помощь, которую вы могли мне оказать.


person vincent_chapron    schedule 02.12.2015    source источник


Ответы (1)


Создание подобных подколлекций выполнимо, но сложно с v1 платформы API, так как это требует создания множества настраиваемых классов (с v2 это будет проще).

Я бы посоветовал использовать следующую структуру:

GET /books?people=/people/3: получить все книги, принадлежащие людям 3

Это легко сделать с помощью встроенного поискового фильтра платформы API.

Затем, если вам нужна поддержка гипермедиа (кстати, она вам действительно нужна - я имею в виду, может ли ваш клиент разыменовать такие ссылки гипермедиа?), Вам понадобится can создать собственный нормализатор Symfony, украшающий Dunglas\ApiBundle\JsonLd\Serializer\ItemNormalizer (сервис api.json_ld.normalizer.item), предоставляемый платформой API, и добавляя ссылку на /books?people=/people/3 для свойства books .

Если вы все еще хотите идти по начатому пути, вам нужно использовать Dunglas\ApiBundle\Hydra\Serializer\CollectionNormalizer для нормализации вашей коллекции в формате Hydra. Вы по-прежнему можете украсить ItemNormalizer, чтобы он указывал на URL-адрес вашей пользовательской коллекции.

Надеюсь, это поможет.

person Kévin Dunglas    schedule 02.12.2015