We are happy to present you the second guest post of the series “Community Highlights” started at the beginning of the year by Loïc Frémont and his story about “Monofony” – a Symfony starter based on Sylius internals. This time you can read about one of our most popular components – Sylius Resource Bundle. Thanks to Stéphane Decock, who is the author of this article, you can now find out how it can help you in your Symfony projects!
To quote Sylius Core Team, I would say: “…we noticed a lot of duplicated code across all controllers. …we wanted something simpler and more flexible.”
That is definitely what SyliusResourceBundle is. It avoids duplicate code, it simplifies CRUD generation, but not only.
In this post, I will try my best to describe this bundle and also give you examples to show how time-saving it is.
Let me introduce myself. I am Stéphane Decock, a Web developer at BeHappy Communication. A French web agency that offers (among other services) solutions for the digital transition to any company.
I am often asked to generate basic or more complex CRUD interfaces. Every solution needs it.
For many years and multiple projects, I have been trying to get a very generic solution for a rapid base development. Like creating users, groups, access rights, customers, products, web domains, and so on…
After developing 2 shops under Sylius, other projects came but in different fields. One ERP for an import/export company and two internal projects for mail routing and the platform for users that comes with it.
The first thing I tried was to reuse some of the knowledge I had acquired in developing shops for those new projects.
There comes SyliusResourceBundle.
This whole post will contain lines of code. All this code is done with a Symfony4 application (with Symfony 4 directory structure) under the “App” namespace (in “src/” directory).
The configuration files are under “config” dir.
As stated in the description, Sylius Resource Bundle helps to generate basic CRUD. But to my mind, it goes far further than that.
Let’s have a look at what it provides, and how it could help you:
The resource is the basis of this bundle. This concept aims at solving inheritance problems in an application. Indeed, if you develop a final application that you are sure no one will extend, this concept is a bit overkilled. Nevertheless, it’s really easy to implement and the benefits of the other functionalities are worth it.
First of all, a resource is a Doctrine Entity. You create the PHP class and declare its mapping. So far, nothing new.
Then you inform Sylius about its existence with this bunch of lines:
sylius_resource:
resources:
app.user:
classes:
model: App\Entity\User
See this doc for more detailed installation and configuration.
Now, Sylius is aware of the Entity, and it will be able to start working.
Let’s talk about one of the now available features: Factories.
The basic aim of this feature is to be sure of the object you inject into your code. If your entity just inherited from an other one (let’s say, Sylius native User), the factory will now return your user (App\Entity\User) and no longer Sylius\User\Model\User. This is important, and with the use of SyliusResourceBundle, you must no longer do something like $user = new User();
but more something like : $user = $this->userFactory->createNew();
The createNew() method is generated by default and returns a new empty instance of a resource.
Another feature is: Repositories
One of the advantages of SyliusResourceBundle is that you don’t have to create a class for each and every repository. A generic one is now available at Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository and contains all basic features you might need (ie. add, remove, paginating, and obviously, find, findBy, …)
This means that in 70% of use cases, you won’t even have to worry about creating a new Repository, you will simply inject the generic repository into your service and access to whatever you need.
One of the most time-saving features.
Sylius will also generate controllers for your entities. Like repositories, it’s a generic one, containing methods to index, show, create, update, delete, bulkDelete your entities. Combined with events triggered during those actions, you might not even need to create a controller at all for 90% of the time. The 10% left will be for non-CRUD actions and very specific behaviours that cannot be properly handled with events.
As stated in the docs, Sylius creates forms for you.
Basically, if you want to get a form for all the fields of your entity, the generic one is ok. But most of the time, there are some fields you don’t want to display. So you’ll have to create a new Form for this entity. See this doc tu find out more.
You can now configure your routes for this resource. Even if the doc specifies a generic method to create multiple routes at once, I do prefer to declare them one by one, for a more specific declaration.
And for this point, read the doc that is well written and very detailed.
We’ve now seen the basic functionalities that come with SyliusResourceBundle. Let’s now have a look at how it saves time
One of the biggest advantages of this bundle is that from now on, for basic actions like create, read, update and delete, you will not have to write a single line of code. The repositories offer methods to fetch and update your entities, controllers will call factories to create entities, create forms, display them, and handle the submit.
Even for more specific cases, this structure will help you follow Symfony SOC (Separation Of Concerns) model, and work with events rather than have a monolithic controller.
If you’re building an app that will be overridden (like a modular one), ResourceBundle will also handle it.
In my opinion, the biggest drawback of this bundle is that you’ll have to write many configuration lines to have the first entities work. That might be disturbing at first.
Another small drawback is that you can no longer have entities with a composite primary key. ResourceBundle is expecting a primary key with a unique ID.
No matter if you are creating a large application or a small prototype, once mastered, SyliusResourceBundle will save you a lot of time.
Furthermore, since it has been outsourced from Sylius core, we might expect from it more functionalities to come.
If you like this article and you are also working on some Sylius-based project, contact us! We will be glad to share any article about live use cases of Sylius bundles in your Symfony apps.
PS. Just a few days ago, a new website based on Monofony popped up: https://zones-activites-ariege.fr/. It’s made by our Solution Partner – Emagma and we can expect a case study soon. You can also enjoy a dedicated #monofony channel on our Slack: sylius.com/slack. We are happy to see our Community’s projects grow! 😉