|
| 1 | +Flex: Compose your Application |
| 2 | +============================== |
| 3 | + |
| 4 | +After reading the first part of this tutorial, you have decided that Symfony was |
| 5 | +worth another 10 minutes. Great choice! In this second part, you'll learn about |
| 6 | +Symfony Flex: the amazing tool that makes adding new features as simple as running |
| 7 | +one command. It's also the reason why Symfony is ideal for a small micro-service |
| 8 | +or a huge application. Curious? Perfect! |
| 9 | + |
| 10 | +Symfony: Start Micro! |
| 11 | +--------------------- |
| 12 | + |
| 13 | +Unless you're building a pure API (more on that soon!), you'll probably want to |
| 14 | +render HTML. To do that, you'll use `Twig`_. Twig is a flexible, fast, and secure |
| 15 | +template engine for PHP. It makes your templates more readable and concise; it also |
| 16 | +makes them more friendly for web designers. |
| 17 | + |
| 18 | +Is Twig already installed in our application? Actually, not yet! And that's great! |
| 19 | +When you start a new Symfony project, it's *small*: only the most critical dependencies |
| 20 | +are included in your ``composer.json`` file: |
| 21 | + |
| 22 | +.. code-block:: text |
| 23 | +
|
| 24 | + "require": { |
| 25 | + "...", |
| 26 | + "symfony/console": "^4.1", |
| 27 | + "symfony/flex": "^1.0", |
| 28 | + "symfony/framework-bundle": "^4.1", |
| 29 | + "symfony/yaml": "^4.1" |
| 30 | + } |
| 31 | +
|
| 32 | +This makes Symfony different than any other PHP framework! Instead of starting with |
| 33 | +a *bulky* app with *every* possible feature you might ever need, a Symfony app is |
| 34 | +small, simple and *fast*. And you're in total control of what you add. |
| 35 | + |
| 36 | +Flex Recipes and Aliases |
| 37 | +------------------------ |
| 38 | + |
| 39 | +So how can we install and configure Twig? Just run one command: |
| 40 | + |
| 41 | +.. code-block:: terminal |
| 42 | +
|
| 43 | + $ composer require twig |
| 44 | +
|
| 45 | +Two *very* interesting things happen behind the scenes thanks to Symfony Flex: a |
| 46 | +Composer plugin that is already installed in our project. |
| 47 | + |
| 48 | +First, ``twig`` is not the name of a Composer package: it's a Flex *alias* that |
| 49 | +points to ``symfony/twig-bundle``. Flex resolves that alias for Composer. |
| 50 | + |
| 51 | +And second, Flex installs a *recipe* for ``symfony/twig-bundle``. What's a recipe? |
| 52 | +It's a way for a library to automatically configure itself by adding and modifying |
| 53 | +files. Thanks to recipes, adding features is seamless and automated: install a package |
| 54 | +and you're done! |
| 55 | + |
| 56 | +You can find a full list of recipes and aliases by going to `https://symfony.sh`_. |
| 57 | + |
| 58 | +What did this recipe do? In addition to automatically enabling the feature in |
| 59 | +``config/bundles.php``, it added 3 things: |
| 60 | + |
| 61 | +``config/packages/twig.yaml`` |
| 62 | + A configuration file that sets up Twig with sensible defaults. |
| 63 | + |
| 64 | +``config/routes/dev/twig.yaml`` |
| 65 | + A route that helps you debug your error pages. |
| 66 | + |
| 67 | +``templates/`` |
| 68 | + This is the directory where template files will live. The recipe also added |
| 69 | + a ``base.html.twig`` layout file. |
| 70 | + |
| 71 | +Twig: Rendering a Template |
| 72 | +-------------------------- |
| 73 | + |
| 74 | +Thanks to Flex, after one command, you can start using Twig immediately:: |
| 75 | + |
| 76 | + // src/Controller/DefaultController.php |
| 77 | + // ... |
| 78 | + |
| 79 | + + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
| 80 | + |
| 81 | + -class DefaultController |
| 82 | + +class DefaultController extends AbstractController |
| 83 | + { |
| 84 | + /** |
| 85 | + * @Route("/hello/{name}") |
| 86 | + */ |
| 87 | + public function index($name) |
| 88 | + { |
| 89 | + - return new Response("Hello $name!"); |
| 90 | + + return $this->render('default/index.html.twig', [ |
| 91 | + + 'name' => $name, |
| 92 | + + ]); |
| 93 | + } |
| 94 | + |
| 95 | +By extending ``AbstractController``, you now have access to a number of shortcut |
| 96 | +methods and tools, like ``render()``. Create the new template: |
| 97 | + |
| 98 | +.. code-block:: twig |
| 99 | +
|
| 100 | + {# templates/default/index.html.twig #} |
| 101 | + <h1>Hello {{ name }}</h1> |
| 102 | +
|
| 103 | +That's it! The ``{{ name }}`` syntax will print the ``name`` variable that's passed |
| 104 | +in from the controller. If you're new to Twig, welcome! You'll learn more about |
| 105 | +its syntax and power later. |
| 106 | + |
| 107 | +But, right now, the page *only* contains the ``h1`` tag. To give it an HTML layout, |
| 108 | +extend ``base.html.twig``: |
| 109 | + |
| 110 | +.. code-block:: twig |
| 111 | +
|
| 112 | + {# templates/default/index.html.twig #} |
| 113 | + {% extends 'base.html.twig' %} |
| 114 | +
|
| 115 | + {% block body %} |
| 116 | + <h1>Hello {{ name }}</h1> |
| 117 | + {% endblock %} |
| 118 | +
|
| 119 | +This is called template inheritance: our page now inherits the HTML structure from |
| 120 | +``base.html.twig``. |
| 121 | + |
| 122 | +Profiler: Debugging Paradise |
| 123 | +---------------------------- |
| 124 | + |
| 125 | +One of the *coolest* features of Symfony isn't even installed yet! Let's fix that: |
| 126 | + |
| 127 | +.. code-block:: terminal |
| 128 | +
|
| 129 | + $ composer require profiler |
| 130 | +
|
| 131 | +Yes! This is another alias! And Flex *also* installs another recipe, which automates |
| 132 | +the configuration of Symfony's Profiler. What's the result? Refresh! |
| 133 | + |
| 134 | +See that black bar on the bottom? That's the web debug toolbar, and it's your new |
| 135 | +best friend. By hovering over each icon, you can get information about what controller |
| 136 | +was executed, performance information, cache hits & misses and a lot more. Click |
| 137 | +any icon to go into the *profiler* where you have even *more* detailed debugging |
| 138 | +and performance data! |
| 139 | + |
| 140 | +Oh, and as you install more libraries, you'll get more tools (like a web debug toolbar |
| 141 | +icon that shows database queries). |
| 142 | + |
| 143 | +Using the profiler is easy because it configured *itself* thanks to the recipe. |
| 144 | +What else can we install this easily? |
| 145 | + |
| 146 | +Rich API Support |
| 147 | +---------------- |
| 148 | + |
| 149 | +Are you building an API? You can already return JSON easily from any controller:: |
| 150 | + |
| 151 | + /** |
| 152 | + * @Route("/api/hello/{name}") |
| 153 | + */ |
| 154 | + public function apiExample($name) |
| 155 | + { |
| 156 | + return $this->json([ |
| 157 | + 'name' => $name, |
| 158 | + 'symfony' => 'rocks', |
| 159 | + ]); |
| 160 | + } |
| 161 | + |
| 162 | +But for a *truly* rich API, try installing `Api Platform`_: |
| 163 | + |
| 164 | +.. code-block:: terminal |
| 165 | +
|
| 166 | + $ composer require api |
| 167 | +
|
| 168 | +This is an alias to ``api-platform/api-pack``, which has dependencies on several |
| 169 | +other packages, like Symfony's Validator and Security components, as well as the Doctrine |
| 170 | +ORM. In fact, Flex installed *5* recipes! |
| 171 | + |
| 172 | +But like usual, we can immediately start using the new library. Want to create a |
| 173 | +rich API for a ``product`` table? Create a ``Product`` entity and give it the |
| 174 | +``@ApiResource()`` annotation:: |
| 175 | + |
| 176 | + // src/Entity/Product.php |
| 177 | + // ... |
| 178 | + |
| 179 | + use ApiPlatform\Core\Annotation\ApiResource; |
| 180 | + |
| 181 | + /** |
| 182 | + * @ORM\Entity() |
| 183 | + * @ApiResource() |
| 184 | + */ |
| 185 | + class Product |
| 186 | + { |
| 187 | + /** |
| 188 | + * @ORM\Id |
| 189 | + * @ORM\GeneratedValue(strategy="AUTO") |
| 190 | + * @ORM\Column(type="integer") |
| 191 | + */ |
| 192 | + private $id; |
| 193 | + |
| 194 | + /** |
| 195 | + * @ORM\Column(type="string") |
| 196 | + */ |
| 197 | + private $name; |
| 198 | + |
| 199 | + /** |
| 200 | + * @ORM\Column(type="string") |
| 201 | + */ |
| 202 | + private $price; |
| 203 | + |
| 204 | + // ... |
| 205 | + } |
| 206 | + |
| 207 | +Done! You now have endpoints to list, add, update and delete products! Don't believe |
| 208 | +me? List your routes by running: |
| 209 | + |
| 210 | +.. code-block:: terminal |
| 211 | +
|
| 212 | + $ php bin/console debug:router |
| 213 | +
|
| 214 | +.. code-block:: text |
| 215 | +
|
| 216 | + ------------------------------ -------- ------------------------------------- |
| 217 | + Name Method Path |
| 218 | + ------------------------------ -------- ------------------------------------- |
| 219 | + api_products_get_collection GET /api/products.{_format} |
| 220 | + api_products_post_collection POST /api/products.{_format} |
| 221 | + api_products_get_item GET /api/products/{id}.{_format} |
| 222 | + api_products_put_item PUT /api/products/{id}.{_format} |
| 223 | + api_products_delete_item DELETE /api/products/{id}.{_format} |
| 224 | + ... |
| 225 | + ------------------------------ -------- ------------------------------------- |
| 226 | +
|
| 227 | +Easily Remove Recipes |
| 228 | +--------------------- |
| 229 | + |
| 230 | +Not convinced yet? No problem: remove the library: |
| 231 | + |
| 232 | +.. code-block:: terminal |
| 233 | +
|
| 234 | + $ composer remove api |
| 235 | +
|
| 236 | +Flex will *uninstall* the recipes: removing files and un-doing changes to put your |
| 237 | +app back in its original state. Experiment without worry. |
| 238 | + |
| 239 | +More Features, Architecture and Speed |
| 240 | +------------------------------------- |
| 241 | + |
| 242 | +I hope you're as excited about Flex as I am! But we still have *one* more chapter, |
| 243 | +and it's the most important yet. I want to show you how Symfony empowers you to quickly |
| 244 | +build features *without* sacrificing code quality or performance. It's all about |
| 245 | +the service container, and it's Symfony's super power. |
| 246 | + |
| 247 | +.. _`https://symfony.sh`: https://symfony.sh |
| 248 | +.. _`Api Platform`: https://api-platform.com/ |
| 249 | +.. _`Twig`: https://twig.symfony.com/ |
0 commit comments