|
| 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 perfect 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 an 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 bundle 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: it's added only in the ``dev`` |
| 66 | + environment. |
| 67 | + |
| 68 | +``templates/`` |
| 69 | + This is the directory where template files will live. The recipe also added |
| 70 | + a ``base.html.twig`` layout file. |
| 71 | + |
| 72 | +Twig: Rendering a Template |
| 73 | +-------------------------- |
| 74 | + |
| 75 | +Thanks to Flex, after one command, you can start using Twig immediately:: |
| 76 | + |
| 77 | + // src/Controller/DefaultController.php |
| 78 | + // ... |
| 79 | + |
| 80 | + + use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; |
| 81 | + |
| 82 | + -class DefaultController |
| 83 | + +class DefaultController extends AbstractController |
| 84 | + { |
| 85 | + /** |
| 86 | + * @Route("/hello/{name}") |
| 87 | + */ |
| 88 | + public function index($name) |
| 89 | + { |
| 90 | + - return new Response("Hello $name!"); |
| 91 | + + return $this->render('default/index.html.twig', [ |
| 92 | + + 'name' => $name, |
| 93 | + + ]); |
| 94 | + } |
| 95 | + |
| 96 | +By extending ``AbstractController``, you now have access to a number of shortcut |
| 97 | +methods and tools, like ``render()``. Create the new template: |
| 98 | + |
| 99 | +.. code-block:: twig |
| 100 | +
|
| 101 | + {# templates/default/index.html.twig #} |
| 102 | + <h1>Hello {{ name }}</h1> |
| 103 | +
|
| 104 | +That's it! The ``{{ name }}`` syntax will print the ``name`` variable that's passed |
| 105 | +in from the controller. If you're new to Twig, welcome! You'll learn more about |
| 106 | +its syntax and power later. |
| 107 | + |
| 108 | +But, right now, the page *only* contains the ``h1`` tag. To give it an HTML layout, |
| 109 | +extend ``base.html.twig``: |
| 110 | + |
| 111 | +.. code-block:: twig |
| 112 | +
|
| 113 | + {# templates/default/index.html.twig #} |
| 114 | + {% extends 'base.html.twig' %} |
| 115 | +
|
| 116 | + {% block body %} |
| 117 | + <h1>Hello {{ name }}</h1> |
| 118 | + {% endblock %} |
| 119 | +
|
| 120 | +This is called template inheritance: our page now inherits the HTML structure from |
| 121 | +``base.html.twig``. |
| 122 | + |
| 123 | +Profiler: Debugging Paradise |
| 124 | +---------------------------- |
| 125 | + |
| 126 | +One of the *coolest* features of Symfony isn't even installed yet! Let's fix that: |
| 127 | + |
| 128 | +.. code-block:: terminal |
| 129 | +
|
| 130 | + $ composer require profiler |
| 131 | +
|
| 132 | +Yes! This is another alias! And Flex *also* installs another recipe, which automates |
| 133 | +the configuration of Symfony's WebProfilerBundle. What's the result? Refresh! |
| 134 | + |
| 135 | +See that black bar on the bottom? That's the web debug toolbar, and it's your new |
| 136 | +best friend. By hovering over each icon, you can get information about what controller |
| 137 | +was executed, performance information, cache hits & misses and a lot more. Click |
| 138 | +any icon to go into the *profiler* where you have even *more* detailed debugging |
| 139 | +and performance data! |
| 140 | + |
| 141 | +Oh, and as you install more libraries, you'll get more tools (like a web debug toolbar |
| 142 | +icon that shows database queries). |
| 143 | + |
| 144 | +Using the profiler is easy because it configured *itself* thanks to the recipe. |
| 145 | +What else can we install this easily? |
| 146 | + |
| 147 | +Rich API Support |
| 148 | +---------------- |
| 149 | + |
| 150 | +Are you building an API? You can already return JSON easily from any controller:: |
| 151 | + |
| 152 | + /** |
| 153 | + * @Route("/api/hello/{name}") |
| 154 | + */ |
| 155 | + public function apiExample($name) |
| 156 | + { |
| 157 | + return $this->json([ |
| 158 | + 'name' => $name, |
| 159 | + 'symfony' => 'rocks', |
| 160 | + ]); |
| 161 | + } |
| 162 | + |
| 163 | +But for a *truly* rich API, try installing `Api Platform`_: |
| 164 | + |
| 165 | +.. code-block:: terminal |
| 166 | +
|
| 167 | + $ composer require api |
| 168 | +
|
| 169 | +This is an alias to ``api-platform/api-pack``, which has dependencies on several |
| 170 | +other packages, like Symfony's Validator and Security components, as well as the Doctrine |
| 171 | +ORM. In fact, Flex installed *5* recipes! |
| 172 | + |
| 173 | +But like usual, we can immediately start using the new library. Want to create a |
| 174 | +rich API for a ``product`` table? Create a ``Product`` entity and give it the |
| 175 | +``@ApiResource()`` annotation:: |
| 176 | + |
| 177 | + // src/Entity/Product.php |
| 178 | + // ... |
| 179 | + |
| 180 | + use ApiPlatform\Core\Annotation\ApiResource; |
| 181 | + |
| 182 | + /** |
| 183 | + * @ORM\Entity() |
| 184 | + * @ApiResource() |
| 185 | + */ |
| 186 | + class Product |
| 187 | + { |
| 188 | + /** |
| 189 | + * @ORM\Id |
| 190 | + * @ORM\GeneratedValue(strategy="AUTO") |
| 191 | + * @ORM\Column(type="integer") |
| 192 | + */ |
| 193 | + private $id; |
| 194 | + |
| 195 | + /** |
| 196 | + * @ORM\Column(type="string") |
| 197 | + */ |
| 198 | + private $name; |
| 199 | + |
| 200 | + /** |
| 201 | + * @ORM\Column(type="string") |
| 202 | + */ |
| 203 | + private $price; |
| 204 | + |
| 205 | + // ... |
| 206 | + } |
| 207 | + |
| 208 | +Done! You now have endpoints to list, add, update and delete products! Don't believe |
| 209 | +me? List your routes by running: |
| 210 | + |
| 211 | +.. code-block:: terminal |
| 212 | +
|
| 213 | + $ php bin/console debug:router |
| 214 | +
|
| 215 | +.. code-block:: text |
| 216 | +
|
| 217 | + ------------------------------ -------- ------------------------------------- |
| 218 | + Name Method Path |
| 219 | + ------------------------------ -------- ------------------------------------- |
| 220 | + api_products_get_collection GET /api/products.{_format} |
| 221 | + api_products_post_collection POST /api/products.{_format} |
| 222 | + api_products_get_item GET /api/products/{id}.{_format} |
| 223 | + api_products_put_item PUT /api/products/{id}.{_format} |
| 224 | + api_products_delete_item DELETE /api/products/{id}.{_format} |
| 225 | + ... |
| 226 | + ------------------------------ -------- ------------------------------------- |
| 227 | +
|
| 228 | +Easily Remove Recipes |
| 229 | +--------------------- |
| 230 | + |
| 231 | +Not convinced yet? No problem: remove the library: |
| 232 | + |
| 233 | +.. code-block:: terminal |
| 234 | +
|
| 235 | + $ composer remove api |
| 236 | +
|
| 237 | +Flex will *uninstall* the recipes: removing files and un-doing changes to put your |
| 238 | +app back in its original state. Experiment without worry. |
| 239 | + |
| 240 | +More Feature, Architecture and Speed |
| 241 | +------------------------------------ |
| 242 | + |
| 243 | +I hope you're as excited about Flex as I am! But we still have *one* more chapter, |
| 244 | +and it's the most important yet. I want to show you how Symfony empowers you to quickly |
| 245 | +build features *without* sacrificing code quality or performance. It's all about |
| 246 | +the service container, and it's Symfony's super power. |
| 247 | + |
| 248 | +.. _`https://symfony.sh`: https://symfony.sh |
| 249 | +.. _`Api Platform`: https://api-platform.com/ |
0 commit comments