sonata-project / SonataAdminBundle

The missing Symfony Admin Generator
https://docs.sonata-project.org/projects/SonataAdminBundle
MIT License
2.11k stars 1.26k forks source link

Use Sonata Admin for data coming from REST API #7534

Closed cezar77 closed 3 years ago

cezar77 commented 3 years ago

Feature Request

An Admin class must be registered as a service like this:

# config/services.yaml

services:
    # ...
    admin.category:
        class: App\Admin\CategoryAdmin
        arguments: [~, App\Entity\Category, ~]
        tags:
            - { name: sonata.admin, manager_type: orm, label: Category } 

It requires an entity as second argument and either orm or odm passed as value to the manager_type tag.

I have a specific case where part of the data we're dealing with comes from a REST API. It would be great if we could build a client inside Sonata Admin to communicate with the RESTful service and display the data. We use Guzzle to make HTTP requests to the REST API.

Would it be possible to create a custom manager_type and plug it in instead of orm or odm?

Is my use case too specific, or are there maybe other people interested in a feature like this.

An entity that maps the REST API endpoint would be still required, but not persisted into a database.

VincentLanglet commented 3 years ago

Hi

I would say it's possible to write your own ModelManagerInterface with specific create/update/delete/findBy/executeQuery/... methods. All the database interaction are done by the ModelManager, so I you make call API instead it should work.

I would recommend you to use SonataAdmin 4 first because the model manager interface is simpler.

But I would say it's not a feature we'll add to the core of sonata:

So I'm closing the feature request for now ; maybe another @sonata-project/contributors see it differently

cezar77 commented 3 years ago

Hi Vincent,

thanks for the reply. I looked through the source code of SonataAdminBundle as well as SonataDoctrineORMAdminBundle and SonataDoctrineMongodbAdminBundle.

To me it seems that Sonata Admin picks the value from the tag manager_type here at this line: https://github.com/sonata-project/SonataAdminBundle/blob/c823f2e33ab3ef7362b077e6ee9033dfe9d70d9d/src/DependencyInjection/Compiler/AddDependencyCallsCompilerPass.php#L302

After that it creates the array $defaultAddServices.

It looks like I'll have to write services for all of these:

            'model_manager' => sprintf('sonata.admin.manager.%s', $managerType),
            'data_source' => sprintf('sonata.admin.data_source.%s', $managerType),
            'field_description_factory' => sprintf('sonata.admin.field_description_factory.%s', $managerType),
            'form_contractor' => sprintf('sonata.admin.builder.%s_form', $managerType),
            'show_builder' => sprintf('sonata.admin.builder.%s_show', $managerType),
            'list_builder' => sprintf('sonata.admin.builder.%s_list', $managerType),
            'datagrid_builder' => sprintf('sonata.admin.builder.%s_datagrid', $managerType),

I understand that a new bundle would be needed if this is to be made available as an option for other developers. As you said, every REST API is different and it's hard to make a generic client.

Maybe we should think more of an agnostic approach, where developers can use SonataAdminBundle without orm or odm, specifying the data handling by themselves.

I would like to see an example in the documentation about this.

I'll play with this as much as the time allows and will check if I can achieve something with a custom ModelManager.

VincentLanglet commented 3 years ago

You can use

tags:
      - { name: sonata.admin, manager_type: orm, model_manage: App\ModelManager\MyManager }

It will only override the model_manager for an admin.

Or use the default_admin_services config.

See https://docs.sonata-project.org/projects/SonataAdminBundle/en/4.x/cookbook/recipe_overwrite_admin_configuration/#overwrite-admin-configuration

I would like to see an example in the documentation about this.

PR is welcomed.

cezar77 commented 3 years ago

Thank you for the explanation.

The first option is feasible in my case. The data are stored in MySQL, it is just some specific data we fetch from an API. Therefore I can't change the default_admin_services in the config. It has to be done for an admin service specifically.

I'll try it out and report about the outcome.