 I think we are on time, so let's start. Welcome. My name is Kevin Porras-Sumbado. I'm Director of Technology at Manatee. You can find me on the web using kporas07, Twitter, Drupalore, GitHub, whatever. I work for Manatee. This is a full stack web agency with a human-first collaborative approach in design and excellence in delivery. We are based in Costa Rica. So you are welcome to Costa Rica. If you want to go, what will we learn? We'll get a quick overview about what is symphony, why symphony 4. We'll talk about flex, about maker bundle, about song use for bundles. Then we'll, again, take a quick overview to entities, migrations, and controllers. Then we are going to put all together. And finally, we'll get some final talks. So let's start. Symphony is a set of PHP components, a web application framework, a philosophy, and a community, all working together in harmony. These are song stats taken from symphony main page. So as you can see, it's a pretty used PHP framework, and actually we use that in Drupal Lake. Not this version, but we use symphony in Drupal Lake. So why symphony 4? This major version was released on November 30, last year. It used a micro-architecture, for example. Symphony 4 application is 70% smaller than the same application in symphony 3. It has a better directory structure. We have flex in the core of symphony, and we have maker bundle. We are going to see what is one of these items. So let's start with flex. Flex is a way to install bundles using recipes. So you run composer-require command, and it also downloads the recipe and executes the recipe that you require to install that bundle. There is a screenshot, it's an example. We have two sources for the recipes, the core recipes and the country recipes. If there is a country recipe, it asks you if you want to execute the recipe. This is an example of JMS serializer bundle installation. It's saying that this is a country recipe. So do you want to execute the recipe? You say yes. So it executes the recipe. And finally, it tells you, hey, some files may have been created or updated to configure your new package. Feel free to review, edit and commit them. These files are yours. So it edited or created the files that it needs to configure the bundle, and now you are free to modify whatever you need. Another great thing of symphony 4 is the maker bundle. This allows you to do some code scaffolding. So this is an example, a list of all the commands that are available with this bundle. So for example, you can make out command controller, CRUD, entity, fixtures, form, functional test, migrations, serializer encoder, subscriber, tweak extension, unit test, validator, voter, and more commands are being added to the bundle. Okay, let's start talking about some useful bundles that I require for the demo application that I made for this session. So first and all, first user bundle, this is the most popular bundle in symphony to manage user. It's really, really helpful. You can find the documentation in that link. And the installation is, let's say, easy. There is kind of a list of dependency on symphony slash templating. So first and all, you need to download symphony slash templating user using simple composer required command. Then you configure that package. You do that in config slash packages slash framework and you add the tweak engine templating. Now you are supposed to be ready to install the user bundle. However, the user bundle, I mean, when I was creating this, at least the user bundle didn't have a flex recipe. So it tries to install the bundle from an auto-generated recipe and it wasn't working at the moment. I haven't checked that during these days, but I know the community is actively working on creating recipes for the bundle that still doesn't have it. So I won't be surprised if the bundle really have a recipe. That would be great. So if you run this command, it downloads the bundle, but it fails executing the recipe. So it's saying that there is a config child node that needs to be configured. So you go and create the config file that should be located on config slash packages slash force user. Now each bundle has its own config file. So here you configure this bundle, the db driver that was the error that we had here. You set the user class, the firewall name, and some stuff for the emails that this bundle will send. Next, you need to create a user class if you don't want to use the default user class. So in this example, I'm just creating a normal entity class. This class extends from the user that I've been named here, but it's the user class that the bundles provides, and you can add properties, you can add functions, you can add whatever you need to your user class. Obviously, this is an entity class, so you need to link that to a repository class that you should also create. Actually we'll see later in this presentation that you don't need to manually create them. You can generate them using maker bundle as we saw a couple of slides ago. Then to continue configuring the force user bundle, you need to configure security. So here you need to set the encoder, the providers, and you need to create a firewall that will use your recently installed bundle. So we are creating a firewall named main, and we are setting the force user bundle for this firewall. Last but not least, you need to configure roots. In order to do this, you create a file under config, and you name that force underscore user, and you're saying that you import all of the resources of the roots that these bundles provides at this path. If you don't want to import all of the roots, you can select what roots you want to import and you can do that. You can find more about this in the bundle documentation, but it's pretty easy to do. Our next bundle, it is JMS serializer bundle. This is an optional dependency for our next bundle, but it's pretty powerful, so if you want to create an API link. What we are going to do, it's a really good bundle. So for the installation, it's only a composer command, and that's all. Next bundle, force rest bundle, it's a developer friendly way to create rest APIs. You can find the documentation in that link, and the installation is, again, pretty simple. This is thanks to Flex. So you only run composer required command, and you go and edit the configuration file as you need it. In this example, here I added some rules for the format listeners. I'm saying that if the path is under slash API, the fallback format is JSON, and if it's any other path, the fallback format is HTML. This is useful so that if you get an exception, all exceptions under the last API are thrown in JSON, and all exceptions under every other path are thrown in HTML. If you are creating an API, you don't want that your API throws exceptions in HTML. You want that it throws exception in JSON. So you can do that using this. Our next bundle is the admin bundle. We are creating a pretty nice API, but we want to manage the entities on this API, and we don't want to complicate creating the backend. So we are just using EC admin bundle. It allows you to create the backend in a really fast way. The documentation can be found here, and the installation is just composer required admin and modify the configuration file. In this case, this is all that you need in your configuration file. I mean, you have a lot more options, but if you only want a simple backend for the user entity, you only need to add in the configuration file, the EC admin key, then entities key, and finally, the entities that you want that EC admin manage for you. In this case, only user, and that's enough. In that way, you have the index for the user. You have create, you have retrieve, you have update, you have delete, you have search, you have pretty much everything that you need to manage this entity. Another bundle, and this is really, really useful, is Nelmio API.bundle. This allows you to create documentation for your API, so you don't need to bother about creating documents and keeping those documents updated. Now, this is going to be in your code, and it will generate the documentation, and you could interact with that documentation page. We are going to see that later. Again, you can find the bundle documentation at that link, and the installation is again simple, composite required command, and edit the configuration file. For example, I'm not sure if it reads so well, sorry about that. But for example, we have a key documentation. Here you have info. In the info, you list title, description, and version for your API. Then you have a key named security definitions, where you define how your app is going to be authenticated. In this case, I'm defining an authentication named bitter, and saying its type is API key. It's actually not an API key, but from the types available that works for us. You're saying that it's in header, and the name of the header is authorization. You can document paths here, but you only document paths that are not being provided by your custom code. So in this example, in my custom code, it's not being provided the path slash API slash login check that's provided by a bundle. We are going to see. So I can go to that bundle and edit the code to get the documentation. So I need to create the documentation in this bundle config file. In Elmio API doc bundle config file. So here you can add tags, description, parameters, responses, and all what you need to document this endpoint. Finally, you have areas where you will find path patterns that will fetch API documentation. In this example, we are saying a slash API will be documented. Our next bundle, Lexic JWT authentication bundle, we are authenticating our API using JSON web tokens. This bundle provides that functionality in a simple way. The documentation is available here. And for the installation, it's a little more complex than the other bundles, but it's not so difficult. So let's see. Composer required, as you can imagine at this moment. And you need to generate the keys using open SSL commands, because this is a pair of keys, private and public. And you need to edit the configuration file, then you configure security, and you configure routine. So for the configuration file, you need to set the private keypad, the public keypad, the passphrase for your private key, and the token TTL. That is the time to leave for the JSON web token that you are going to generate. These are the firewalls that you are creating. You are creating a firewall for the API login, and you are creating a firewall for all of the rest of the API. And here you are just importing a route that is provided by this module, that is, slash API, slash login check. The one that we documented in the previous bundle. Another bundle, Nelmiocourse Bundle. It's a simple and effective way to configure cores. Actually, it's pretty easy. I was working on a project, and I had forgotten to configure cores. Then the front developer said, hey, what about cores? Oh, I forgot it. What can I do? Google it. Oh, Nelmiocourse Bundle. And it was really, really easy to configure. The documentation can be found here. The installation is just Composer Required Cores. And the configuration file is like this. You have a default section, and then you have a section for every path on your API. So for example, in a slash API, you are saying that the origin allows rejects. We are saying that here. And then the allowsOrigin variable that we are taking that as most of all the other configuration that we have already seen. We are taking that from environment bars. So I just put that .m file at the root of my project, and it takes all those values. Now we are going to create an entity. We are obviously using Maker Bundle to create an entity. So console, make column entity. That's an interactive command that it's going to ask you the properties, the type of those properties, and some characteristics of those properties. We are going to see that in the next slide. Then when you do that, if you want, you can edit your entity. You can add properties. You can add more annotations. You can add every function that you require. And that's all. Obviously, you can also add functions to the repository that it generates if that's necessary for you. This is how it looks. You invoke the command. It asks you for the name of the entity. Then for the property name, the fill type. And in this case, I said it was a string. So the fill length. Is this field nullable? Yes or no? And it says, hey, I created this file. Or hey, I updated this file. Finally, when you finish doing this, it says, next, when you are ready, create a migration with make column migration. So let's create a migration. It's just a matter of ruining that command. It creates you the migration classes. That's all. It now says, next, review a new migration. And then ruin the migration using doctrine column migrations column migrate to update your database schema. Pretty easy. Then we are going to create our controller. This is a class that should be under SRC Lush Controller. And for this specific application, we are going to make that class extents from false res bundle controller, false res controller. For the functions naming, we are following the conventions specified in the documentation in order to get automatic routing generation. So for example, we have an entity named nodes. And we want to create the endpoint to get one node. So you pass the node ID. And you get that specific node. So the naming that I should give to the function is get node action. Let's see. This is how Nelmu API documentation looks like. So you are saying this is a get method. You are setting security. It's named bitter, like we did in the bundle configuration. You set tags. You can specify the responses and the parameters. And that's all what the bundle needs. We are going to see how it looks in a few moments. And please note here that the parameter we are saying it's in path and that it's type integer. So let's see the function. Its name get node action. Since the parameter is in path, so the parameter is received as a function argument. So you have it here. You can do all the logic that you need to do there. For example, if you need, you can throw exceptions. Here, I'm throwing a photo for exception. Node not fun. Here, I'm throwing a photo tree exception. Accent denied. And if everything is OK, I can call the view function to create my view. And then I can return the view. And here, I'm returning JSON. Here, node is my node entity. And we're only doing this and we're turning that entity in JSON. So that's great. So let's put all together. How does this look? This is the main screen for notes. Sorry, for Nelmio API.bundle. Here, we have an authorized button. And you can see. I hope you can see. There is a log icon. Here, we have the logging endpoint. And here are the nodes endpoint. You can see there is no log icon in the logging endpoint. And there is log icon in all of the other endpoints. This log icon is open. It means we have not authenticated to the API. So if we are going to use that, we are going to get Accent Denied. Don't do that. So let's use this one first. It asks you for the credentials. All of this is happening in the Nelmio API.bundle. So you can test the API using the same bundle. And that's what we did here. So it's really, really great. So for example, it's asking you for the username and the password. You click Execute. Here you get the cure equivalent command, the response body. You can see here is a token variable. So you copy that token. That's your JSON web token. And now you can click Alterize. You remember the button that was here. And it gives you this popup. You are giving the value. The value is the token that you just got. But prefix with bidder. And then you click Alterize. Once you click Alterize, you can click Done. And now all of the log icons are closed. That means you can use those endpoints. For example, the endpoint that we just created was a large API, a large node, a large node ID. So I enter the node ID and click Execute. And we get this again, the cure equivalent command. The request URL and the response body. It contains the ID, the title, the body, that's every property that our nodes entity have. And the user, because our nodes entity also have a user property. And that user property have all of the property of the user. This may not be convenient. For example, it also have the password hash, but it has the password. So we could remove some of these fields if we want to do that. And it's pretty easy to do. Do you remember EC Admin Bundle? Here is how it looks. This is the index page for the user entity. You have search, if you have so many users, you can add user here. If you scroll to the right, I can do that because this is a screenshot. You will find Edit and Delete buttons. Some properties can be changed directly here. The ones that are Booleans. So it's really, really great and really easy to configure. So some final tags, yeah? This is the best symphony version ever. It was released a couple of months ago and it's really, really great. It's really easy to use. There is so much ordering config files. So what else can I say? Give it a try if you have time. All the code examples that we use in this presentation can be found at this GitHub repo. So feel free to check it out. And I don't think we have time for question. We have about one minute. So I'll be around here if you have any question. It's 15.15, so I think that's all the time that I had. Just one invite. There will be Drupal Cam Costa Rica in August 3rd and 4th. So it would be a nice opportunity to go to Costa Rica. We'll be waiting for you. And remember, contribution is printed on Friday. And you can evaluate the session and evaluate the code in those links. So thank you very much.