<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Daniyal Javani</title>
    <description>The latest articles on DEV Community by Daniyal Javani (@daniyaljavani).</description>
    <link>https://dev.to/daniyaljavani</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F369110%2F9e7bfa3f-e916-4caf-9901-ff8bc51a4ffc.jpg</url>
      <title>DEV Community: Daniyal Javani</title>
      <link>https://dev.to/daniyaljavani</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/daniyaljavani"/>
    <language>en</language>
    <item>
      <title>How to Implement a Simple Queue in Symfony</title>
      <dc:creator>Daniyal Javani</dc:creator>
      <pubDate>Sun, 03 Dec 2023 15:38:37 +0000</pubDate>
      <link>https://dev.to/daniyaljavani/how-to-implement-a-simple-queue-in-symfony-530a</link>
      <guid>https://dev.to/daniyaljavani/how-to-implement-a-simple-queue-in-symfony-530a</guid>
      <description>&lt;p&gt;Symfony is a popular PHP framework that provides many features and components to create web applications. One of these components is the Messenger component, which allows you to send and receive messages between different parts of your application or between different applications. In this article, we will see how to use the Messenger component to implement a simple queue system using Redis as the transport layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing the Required Packages
&lt;/h2&gt;

&lt;p&gt;The first step is to install the Messenger component and the Redis adapter for it. You can do this by running the following commands in your project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require symfony/messenger
composer require symfony/redis-messenger
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will add the necessary dependencies to your composer.json file and install them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the Transport
&lt;/h2&gt;

&lt;p&gt;The next step is to configure the transport that will be used to send and receive messages. In this case, we will use Redis, which is a fast and reliable in-memory data store that can act as a message broker. To use Redis, you need to have a Redis server running and accessible from your application. You can use the official Redis Docker image for this purpose.&lt;/p&gt;

&lt;p&gt;To configure the Redis transport, you need to edit the .env file in your project root and uncomment the line that defines the MESSENGER_TRANSPORT_DSN environment variable. This variable holds the connection string to the Redis server and the name of the queue that will be used. For example, if your Redis server is running on localhost on port 6379 and you want to use a queue named messages, you can set the variable as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;MESSENGER_TRANSPORT_DSN=redis://localhost:6379/messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use a different queue name or a different Redis server if you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Creating the Message and the Handler
&lt;/h2&gt;

&lt;p&gt;The next step is to create the message and the handler classes that will be used by the Messenger component. A message is a simple PHP object that represents the data that will be sent or received by the transport. A handler is a PHP class that implements the logic that will be executed when a message is received. You can create these classes using the make:message command provided by the Symfony console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console make:message
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will ask you to enter the name of the message class and the name of the handler class. For this example, we will use SmsNotification as the message class and SmsNotificationHandler as the handler class. The command will generate two files in the src/Message and src/MessageHandler directories respectively. You can edit these files to add the properties and methods that you need for your message and handler.&lt;/p&gt;

&lt;p&gt;For example, the SmsNotification class could have a property that holds the phone number and a property that holds the text of the SMS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Message&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SmsNotification&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$phoneNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$phoneNumber&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;phoneNumber&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$phoneNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getPhoneNumber&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;phoneNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;getText&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The SmsNotificationHandler class could have a method that uses a third-party service to send the SMS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\MessageHandler&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Message\SmsNotification&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Messenger\Handler\MessageHandlerInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SmsNotificationHandler&lt;/span&gt; &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="nc"&gt;MessageHandlerInterface&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__invoke&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;SmsNotification&lt;/span&gt; &lt;span class="nv"&gt;$smsNotification&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Use a third-party service to send the SMS&lt;/span&gt;
        &lt;span class="c1"&gt;// For example, using Twilio:&lt;/span&gt;
        &lt;span class="c1"&gt;// $twilio = new \Twilio\Rest\Client($sid, $token);&lt;/span&gt;
        &lt;span class="c1"&gt;// $twilio-&amp;gt;messages-&amp;gt;create($smsNotification-&amp;gt;getPhoneNumber(), [&lt;/span&gt;
        &lt;span class="c1"&gt;//     'from' =&amp;gt; $from,&lt;/span&gt;
        &lt;span class="c1"&gt;//     'body' =&amp;gt; $smsNotification-&amp;gt;getText(),&lt;/span&gt;
        &lt;span class="c1"&gt;// ]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Routing the Message to the Transport
&lt;/h2&gt;

&lt;p&gt;The next step is to tell the Messenger component which transport to use for each message. You can do this by editing the config/packages/messenger.yaml file and adding a routing section. In this section, you can map each message class to a transport name. For example, to use the Redis transport that we configured earlier for the SmsNotification message, you can add the following lines:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# config/packages/messenger.yaml&lt;/span&gt;
&lt;span class="na"&gt;framework&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;messenger&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;transports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;async&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;%env(MESSENGER_TRANSPORT_DSN)%"&lt;/span&gt;

        &lt;span class="na"&gt;routing&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="c1"&gt;# async is whatever name you gave your transport above&lt;/span&gt;
            &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;App\Message\SmsNotification'&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s"&gt;async&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use different transports for different messages if you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dispatching the Message
&lt;/h2&gt;

&lt;p&gt;The next step is to dispatch the message to the transport. You can do this by using the MessageBusInterface service that is provided by the Messenger component. You can inject this service into any class that needs to send messages, such as a controller, a service, or a command. For example, in a controller, you can dispatch a message like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Message\SmsNotification&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Bundle\FrameworkBundle\Controller\AbstractController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Messenger\MessageBusInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Routing\Annotation\Route&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;#[Route('/home', name: 'app_home')]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;MessageBusInterface&lt;/span&gt; &lt;span class="nv"&gt;$messageBus&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;JsonResponse&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$messageBus&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SmsNotification&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1234567890'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Hello from Symfony!'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Message has been dispatched successfully!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will send the message to the Redis transport, where it will be stored until it is consumed by a worker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Consuming the Message
&lt;/h2&gt;

&lt;p&gt;The final step is to consume the message from the transport and execute the handler. You can do this by using the messenger:consume command provided by the Symfony console:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console messenger:consume async &lt;span class="nt"&gt;-vv&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command will start a worker process that will listen to the async transport (or any other transport that you specify) and handle the messages that are received. The -vv option will enable verbose output that will show you the details of each message and handler. You can also use other options to control the behavior of the worker, such as the number of messages to handle, the memory limit, the signal handling, etc. You can see the full list of options by running:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console messenger:consume &lt;span class="nt"&gt;--help&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also run multiple workers in parallel to increase the throughput of your queue system. You can use tools like Supervisor or Systemd to manage your workers and ensure that they are always running.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we have seen how to use the Messenger component to implement a simple queue system in Symfony using Redis as the transport layer. We have learned how to install the required packages, configure the transport, create the message and the handler, route the message to the transport, dispatch the message, and consume the message. The Messenger component provides a powerful and flexible way to send and receive messages between different parts of your application or between different applications. You can use it to implement various patterns, such as command bus, event bus, query bus, etc. You can also use different transports, such as AMQP, Doctrine, Amazon SQS, Google Pub/Sub, etc. You can find more information and examples in the &lt;a href="https://symfony.com/doc/current/components/messenger.html"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>symfony</category>
      <category>php</category>
      <category>queue</category>
      <category>messenger</category>
    </item>
    <item>
      <title>A Simple Way to Validate API Requests in Symfony</title>
      <dc:creator>Daniyal Javani</dc:creator>
      <pubDate>Wed, 29 Nov 2023 11:43:06 +0000</pubDate>
      <link>https://dev.to/daniyaljavani/a-simple-way-to-validate-api-requests-in-symfony-with-dtos-and-annotations-1ge0</link>
      <guid>https://dev.to/daniyaljavani/a-simple-way-to-validate-api-requests-in-symfony-with-dtos-and-annotations-1ge0</guid>
      <description>&lt;p&gt;Symfony is a popular PHP framework that provides many features to simplify web development. One of these features is the ability to validate API requests using data transfer objects (DTOs) and annotations. In this article, we will see how to use this feature to create a simple API endpoint for creating a post with some related fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a DTO?
&lt;/h2&gt;

&lt;p&gt;A DTO is a class that represents the data that is transferred between different layers of an application, such as the presentation layer and the business layer. A DTO can be used to map the values from the request, validate them, and pass them to the service layer. A DTO can also be used to return the data from the service layer to the presentation layer.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create a DTO in Symfony?
&lt;/h2&gt;

&lt;p&gt;To create a DTO in Symfony, we just need to create a class with some public properties that will hold the values from the request. We can also use annotations to define the validation rules for each property, such as &lt;code&gt;NotBlank&lt;/code&gt;, &lt;code&gt;Type&lt;/code&gt;, &lt;code&gt;Range&lt;/code&gt;, etc. These annotations are provided by the &lt;a href="https://symfony.com/doc/current/validation.html"&gt;Symfony Validator component&lt;/a&gt;, which is a powerful tool for validating data in Symfony.&lt;/p&gt;

&lt;p&gt;Please ensure that all the required packages are installed before starting.install all necessary packages before starting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require symfony/serializer
composer require symfony/validator
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example, let's create a DTO class for creating a post with some related fields, such as title, content, author, category, and tags. We can use the following code to create the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Dto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Validator\Constraints&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nc"&gt;Assert&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;CreatePostDto&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;__construct&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="na"&gt;#[Assert\NotBlank]&lt;/span&gt;
        &lt;span class="na"&gt;#[Assert\Type('string')]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="na"&gt;#[Assert\NotBlank]&lt;/span&gt;
        &lt;span class="na"&gt;#[Assert\Type('string')]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="na"&gt;#[Assert\NotBlank]&lt;/span&gt;
        &lt;span class="na"&gt;#[Assert\Type('string')]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="na"&gt;#[Assert\NotBlank]&lt;/span&gt;
        &lt;span class="na"&gt;#[Assert\Type('string')]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;readonly&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

        &lt;span class="na"&gt;#[Assert\Type('array')]&lt;/span&gt;
        &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;?array&lt;/span&gt; &lt;span class="nv"&gt;$tags&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we have defined the properties of the DTO class and used annotations to specify the validation rules for each property. We have also used the &lt;code&gt;readonly&lt;/code&gt; modifier to make the properties immutable, which means they cannot be changed after the object is created. This is a good practice to ensure the consistency and integrity of the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use a DTO in a controller?
&lt;/h2&gt;

&lt;p&gt;To use a DTO in a controller, we just need to use the class as a dependency in the method of the controller with the annotation &lt;code&gt;#[MapRequestPayload]&lt;/code&gt;. This annotation tells Symfony to automatically map the values from the request into the object of the DTO class. We can also use the &lt;code&gt;#[Route]&lt;/code&gt; annotation to define the route for the controller method.&lt;/p&gt;

&lt;p&gt;For example, let's create a controller method for creating a post using the DTO class we created before. We can use the following code to create the method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Dto\CreatePostDto&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Bundle\FrameworkBundle\Controller\AbstractController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\HttpFoundation\JsonResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\HttpKernel\Attribute\MapRequestPayload&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Routing\Annotation\Route&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;PostController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;#[Route('/api/v1/posts', name: 'app_api_create_post_v1', methods: ['POST'])]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;v1Create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nc"&gt;MapRequestPayload&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;CreatePostDto&lt;/span&gt; &lt;span class="nv"&gt;$createPost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="nc"&gt;JsonResponse&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Here we can use the $createPost object to pass the data to the service layer&lt;/span&gt;
        &lt;span class="c1"&gt;// For simplicity, we will just return the data as a JSON response&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'response'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'ok'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'title'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$createPost&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'content'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$createPost&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;content&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'author'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$createPost&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'category'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$createPost&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;category&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="s1"&gt;'tags'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$createPost&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we have used the &lt;code&gt;#[MapRequestPayload]&lt;/code&gt; annotation to inject the &lt;code&gt;CreatePostDto&lt;/code&gt; object into the controller method. We have also used the &lt;code&gt;#[Route]&lt;/code&gt; annotation to define the route for the method, which is &lt;code&gt;/api/v1/posts&lt;/code&gt; with the &lt;code&gt;POST&lt;/code&gt; method. Inside the method, we can use the &lt;code&gt;$createPost&lt;/code&gt; object to access the data from the request and pass it to the service layer. For simplicity, we will just return the data as a JSON response using the &lt;code&gt;json&lt;/code&gt; method of the &lt;code&gt;AbstractController&lt;/code&gt; class.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to test the API endpoint?
&lt;/h2&gt;

&lt;p&gt;To test the API endpoint, we can use a tool like &lt;code&gt;curl&lt;/code&gt; to send a request to the endpoint with the data we want to create a post. We need to make sure to add the &lt;code&gt;Content-Type: application/json&lt;/code&gt; header to the request, as we are sending the data in JSON format. We can also use the &lt;code&gt;-v&lt;/code&gt; option to see the verbose output of the request and the response.&lt;/p&gt;

&lt;p&gt;For example, let's send a request to the endpoint with the following data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"content"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"In this article, we will see how to use DTOs and annotations to validate API request in Symfony"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"author"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"John Doe"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"category"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"PHP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Symfony"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"API"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Validation"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use the following command to send the request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; http://127.0.0.1:8001/api/v1/posts &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
  "title": null,
  "content": "In this article, we will see how to use DTOs and annotations to validate API request in Symfony",
  "author": "John Doe",
  "category": "PHP",
  "tags": ["Symfony", "API", "Validation"]
}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here is the result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;HTTP/&lt;/span&gt;&lt;span class="mf"&gt;1.1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;422&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;&amp;lt;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;Content-Type:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;application/json&lt;/span&gt;&lt;span class="w"&gt;

&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="s2"&gt;symfony.com&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;errors&lt;/span&gt;&lt;span class="se"&gt;\/&lt;/span&gt;&lt;span class="s2"&gt;validation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Validation Failed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;422&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"detail"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"This value should be of type unknown.&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;title: This value should not be blank."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"violations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"propertyPath"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"This value should not be blank."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"template"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"This value should not be blank."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"{{ value }}"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"null"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"urn:uuid:c1051bb4-d103-4f74-8988-acbcafc7fdc3"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we have successfully created a post using the API endpoint and received the data back as a JSON response.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article, we have seen how to use DTOs and annotations to validate API request in Symfony. This is a simple and elegant way to handle the data from the request, validate it, and pass it to the service layer. We have also seen how to use the &lt;code&gt;#[MapRequestPayload]&lt;/code&gt; annotation to automatically map the values from the request into the object of the DTO class. We have also seen how to test the API endpoint using curl.&lt;/p&gt;

&lt;p&gt;We hope you have enjoyed this article and learned something new. If you have any questions or feedback, please feel free to leave a comment below. Thank you for reading!&lt;/p&gt;

</description>
      <category>symfony</category>
      <category>php</category>
      <category>validate</category>
    </item>
    <item>
      <title>How to Add JWT Login to a Symfony Project</title>
      <dc:creator>Daniyal Javani</dc:creator>
      <pubDate>Tue, 21 Nov 2023 14:06:06 +0000</pubDate>
      <link>https://dev.to/daniyaljavani/how-to-add-jwt-login-to-a-symfony-6-project-3elh</link>
      <guid>https://dev.to/daniyaljavani/how-to-add-jwt-login-to-a-symfony-6-project-3elh</guid>
      <description>&lt;p&gt;In this tutorial, I will show you how to implement a simple JWT authentication system for your Symfony project. JWT stands for JSON Web Token, which is a standard for securely transmitting information between parties as a JSON object. JWT can be used to authenticate users and authorize access to protected resources, such as APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;To follow this tutorial, you will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PHP 8.0 or higher&lt;/li&gt;
&lt;li&gt;Composer&lt;/li&gt;
&lt;li&gt;Symfony CLI&lt;/li&gt;
&lt;li&gt;A database server (MySQL, PostgreSQL, etc.)&lt;/li&gt;
&lt;li&gt;A tool to test your API requests (Postman, Insomnia, etc.)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Creating a New Symfony Project
&lt;/h2&gt;

&lt;p&gt;First, let's create a new Symfony project using the Symfony CLI. Open a terminal and run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;symfony new jwt-test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will create a new Symfony project in the &lt;code&gt;jwt-test&lt;/code&gt; directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing the Required Packages
&lt;/h2&gt;

&lt;p&gt;Next, we need to install some packages that we will use for this tutorial. We will use the Doctrine ORM to interact with the database, the MakerBundle to generate code, and the LexikJWTAuthenticationBundle to handle the JWT authentication.&lt;/p&gt;

&lt;p&gt;To install these packages, run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require symfony/orm-pack
composer require symfony/maker-bundle &lt;span class="nt"&gt;--dev&lt;/span&gt;
composer require lexik/jwt-authentication-bundle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the User Entity
&lt;/h2&gt;

&lt;p&gt;Now we need to create a User entity that will represent our users in the database. We will use the MakerBundle to generate the code for us. Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console make:user
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will ask you some questions about the User entity, such as the class name, the properties, and the password hashing algorithm. You can accept the default values or customize them as you wish. I'll be keeping things simple for this tutorial and sticking with the default settings.&lt;/p&gt;

&lt;p&gt;This will generate the following files:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/Entity/User.php&lt;/code&gt;: The User entity class&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;src/Repository/UserRepository.php&lt;/code&gt;: The User repository class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Configure your database and run the following commands to create the users table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console doctrine:database:create
php bin/console make:migration
doctrine:migrations:migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The final step in the database process is to create a user within the database. You need to first hash your password using this command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console ecurity:hash-password
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Copy the "Password hash" and paste it into the password column of the user. Set the roles column as &lt;code&gt;[]&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuring the Security
&lt;/h2&gt;

&lt;p&gt;Next, we need to configure the security system to use the User entity and the JWT authentication. We will make some changes to the &lt;code&gt;config/packages/security.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;We need to define two firewalls: one for the login endpoint, and one for the API endpoints. The login firewall will use the &lt;code&gt;json_login&lt;/code&gt; authenticator, which will allow us to send the username and password as a JSON object and receive a JWT token in response. The API firewall will use the &lt;code&gt;jwt&lt;/code&gt; authenticator, which will validate the JWT token and grant access to the protected resources.&lt;/p&gt;

&lt;p&gt;To define the firewalls, add the following lines under the &lt;code&gt;firewalls&lt;/code&gt; key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;firewalls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;login&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;^/api/login&lt;/span&gt;
        &lt;span class="na"&gt;stateless&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;json_login&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
            &lt;span class="na"&gt;check_path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/api/login_check&lt;/span&gt;
            &lt;span class="na"&gt;success_handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lexik_jwt_authentication.handler.authentication_success&lt;/span&gt;
            &lt;span class="na"&gt;failure_handler&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;lexik_jwt_authentication.handler.authentication_failure&lt;/span&gt;
    &lt;span class="na"&gt;api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;^/api&lt;/span&gt;
        &lt;span class="na"&gt;stateless&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;jwt&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;~&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;pattern&lt;/code&gt; option defines the URL pattern that matches the firewall. The &lt;code&gt;stateless&lt;/code&gt; option indicates that the firewall does not use sessions or cookies. The &lt;code&gt;check_path&lt;/code&gt; option defines the URL that will handle the login request. The &lt;code&gt;success_handler&lt;/code&gt; and &lt;code&gt;failure_handler&lt;/code&gt; options define the services that will handle the login success and failure events. The &lt;code&gt;jwt&lt;/code&gt; option enables the JWT authenticator.&lt;/p&gt;

&lt;p&gt;Finally, we need to define some access control rules to restrict access to the endpoints based on the user roles. We will use the &lt;code&gt;PUBLIC_ACCESS&lt;/code&gt; role to allow anyone to access the login endpoint, and the &lt;code&gt;IS_AUTHENTICATED_FULLY&lt;/code&gt; role to require a valid JWT token to access the API endpoints.&lt;/p&gt;

&lt;p&gt;To define the access control rules, add the following lines under the &lt;code&gt;access_control&lt;/code&gt; key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;access_control&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;^/api/login&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;roles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;PUBLIC_ACCESS&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;^/api&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;       &lt;span class="nv"&gt;roles&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;IS_AUTHENTICATED_FULLY&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;path&lt;/code&gt; option defines the URL pattern that matches the rule. The &lt;code&gt;roles&lt;/code&gt; option defines the required roles to access the path.&lt;/p&gt;

&lt;p&gt;Here are the final changes that have been made in the &lt;code&gt;config/packages/security.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight diff"&gt;&lt;code&gt;&lt;span class="p"&gt;@@ -10,6 +12,17 @@&lt;/span&gt; security:
                 class: App\Entity\User
                 property: email
     firewalls:
&lt;span class="gi"&gt;+        login:
+            pattern: ^/api/login
+            stateless: true
+            json_login:
+                check_path: /api/login_check
+                success_handler: lexik_jwt_authentication.handler.authentication_success
+                failure_handler: lexik_jwt_authentication.handler.authentication_failure
+        api:
+            pattern:   ^/api
+            stateless: true
+            jwt: ~
&lt;/span&gt;         dev:
             pattern: ^/(_(profiler|wdt)|css|images|js)/
             security: false
&lt;span class="p"&gt;@@ -17,17 +30,9 @@&lt;/span&gt; security:
             lazy: true
             provider: app_user_provider
&lt;span class="err"&gt;
&lt;/span&gt;     access_control:
&lt;span class="gd"&gt;-        # - { path: ^/admin, roles: ROLE_ADMIN }
-        # - { path: ^/profile, roles: ROLE_USER }
&lt;/span&gt;&lt;span class="gi"&gt;+        - { path: ^/api/login, roles: PUBLIC_ACCESS }
+        - { path: ^/api,       roles: IS_AUTHENTICATED_FULLY }
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To create JWT tokens, it is necessary to generate key pairs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console lexik:jwt:generate-keypair
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring the Routes
&lt;/h2&gt;

&lt;p&gt;Next, we need to configure the routes for the login and the API endpoints. We will use the &lt;code&gt;config/routes.yaml&lt;/code&gt; file to define the routes.&lt;/p&gt;

&lt;p&gt;First, we need to define a route for the login endpoint, which will be handled by the &lt;code&gt;api_login_check&lt;/code&gt; controller. This controller is provided by the LexikJWTAuthenticationBundle and will generate and return the JWT token. To define the route, add the following lines to the &lt;code&gt;config/routes.yaml&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;api_login_check&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/api/login_check&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;path&lt;/code&gt; option defines the URL that matches the route. The &lt;code&gt;api_login_check&lt;/code&gt; controller is automatically registered by the bundle, so we don't need to specify the controller name.&lt;/p&gt;

&lt;p&gt;Next, we need to define a route for the API endpoint, which will be handled by our custom controller. We will create this controller in the next step. To define the route, we will use the &lt;code&gt;#[Route]&lt;/code&gt; attribute on the controller class.&lt;/p&gt;

&lt;p&gt;Make a request to the login endpoint to obtain a JWT token.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; http://localhost:8000/api/login_check &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--data&lt;/span&gt; &lt;span class="s1"&gt;'{
    "username": "REPLACE_YOUR_EMAIL",
    "password": "REPLACE_YOUR_PASSWORD"
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating the API Controller
&lt;/h2&gt;

&lt;p&gt;Now we need to create a controller that will handle the API requests. We will use the MakerBundle to generate the code for us. Run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php bin/console make:controller
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will ask you the name of the controller class. You can choose any name you want, but for this tutorial, I will use &lt;code&gt;HomeController&lt;/code&gt;. This will generate the following file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;src/Controller/HomeController.php&lt;/code&gt;: The HomeController class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will use the &lt;code&gt;TokenStorageInterface&lt;/code&gt; service to get the logged-in user and display their email.&lt;/p&gt;

&lt;p&gt;To modify the controller class, replace the content of the &lt;code&gt;src/Controller/HomeController.php&lt;/code&gt; file with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;

&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Controller&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Routing\Annotation\Route&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\HttpFoundation\JsonResponse&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Bundle\FrameworkBundle\Controller\AbstractController&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HomeController&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;AbstractController&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;#[Route('api/home', name: 'app_home')]&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;home&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;TokenStorageInterface&lt;/span&gt; &lt;span class="nv"&gt;$tokenStorage&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt; &lt;span class="kt"&gt;JsonResponse&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$tokenStorage&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getToken&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="nv"&gt;$user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$token&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getUser&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'message'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;sprintf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Welcome to your new controller %s!'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;getEmail&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
            &lt;span class="s1"&gt;'path'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'src/Controller/HomeController.php'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;#[Route]&lt;/code&gt; attribute defines the route for the &lt;code&gt;home&lt;/code&gt; action. The &lt;code&gt;TokenStorageInterface&lt;/code&gt; service is injected as a parameter to the &lt;code&gt;home&lt;/code&gt; method. The &lt;code&gt;getToken&lt;/code&gt; method returns the current authentication token. The &lt;code&gt;getUser&lt;/code&gt; method returns the actual user!&lt;/p&gt;

&lt;p&gt;Make a request to the secured endpoint using the obtained JWT token to get the logged-in user's email.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;--request&lt;/span&gt; POST &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--url&lt;/span&gt; http://localhost:8000/api/home &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Authorization: Bearer REPLACE_YOUR_TOKEN'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--header&lt;/span&gt; &lt;span class="s1"&gt;'Content-Type: application/json'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Congratulations! You've successfully added JWT authentication to your Symfony 6 project. Enjoy the secure authentication mechanism for your APIs.&lt;/p&gt;

</description>
      <category>symfony</category>
      <category>php</category>
      <category>jwt</category>
    </item>
    <item>
      <title>Temporary URL for local driver in Spatie Laravel media library</title>
      <dc:creator>Daniyal Javani</dc:creator>
      <pubDate>Wed, 02 Dec 2020 11:49:35 +0000</pubDate>
      <link>https://dev.to/daniyaljavani/temporary-url-for-local-driver-in-spatie-laravel-media-library-pgf</link>
      <guid>https://dev.to/daniyaljavani/temporary-url-for-local-driver-in-spatie-laravel-media-library-pgf</guid>
      <description>&lt;p&gt;Today’s guide describes the implementation of temporary URL for local driver in &lt;code&gt;spatie/laravel-medialibrary&lt;/code&gt;. We'll accomplish this via &lt;a href="https://laravel.com/docs/8.x/urls#signed-urls"&gt;Laravel signed URLs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you use getTemporaryUrl() function of the &lt;code&gt;laravel-medialibrary&lt;/code&gt; for local driver, you will get the following error:&lt;br&gt;
&lt;em&gt;RuntimeException with message 'This driver does not support creating temporary URLs.'&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The below steps describe how to implement getTemporaryUrl function in your Laravel app.&lt;/p&gt;
&lt;h2&gt;
  
  
  Step 1: Add a private disk to config file
&lt;/h2&gt;

&lt;p&gt;Laravel already comes with local, public and s3 disks and you should add your own disk for private files to &lt;code&gt;config/filesystems&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*
|--------------------------------------------------------------------------
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
| Supported Drivers: "local", "ftp", "sftp", "s3", "rackspace"
|
*/

'disks' =&amp;gt; [
    'private' =&amp;gt; [
        'driver' =&amp;gt; 'local',
        'root' =&amp;gt; storage_path('app/private'),
        'url' =&amp;gt; env('APP_URL').'/private-storage',
        'visibility' =&amp;gt; 'private',
    ],
],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Add files to the private disk
&lt;/h2&gt;

&lt;p&gt;You must ensure that files added to &lt;code&gt;secret-files&lt;/code&gt; collection are automatically added to the private disk.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// in your model

public function registerMediaCollections(): void
{
    $this
       -&amp;gt;addMediaCollection('secret-files')
       -&amp;gt;useDisk('private');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Create a controller that handle file requests
&lt;/h2&gt;

&lt;p&gt;It does nothing but returning the media model instance.&lt;br&gt;
Note: You can even authorise using Laravel policy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Spatie\MediaLibrary\MediaCollections\Models\Media;
use Storage;

class ServePrivateStorage extends Controller
{
    /**
     * Handle the incoming request.
     *
     * @param \Spatie\MediaLibrary\MediaCollections\Models\Media $media
     * @return \Illuminate\Http\Response
     */
    public function __invoke(Media $media)
    {
        // $this-&amp;gt;authorize('view', $media-&amp;gt;model);

        return $media;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Create the controller's signed route
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Route::get('private-storage/{media}/{filename}', 'ServePrivateStorage')
    -&amp;gt;middleware('signed')
    -&amp;gt;name('private-storage');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 5: Now we need a media URL generator class
&lt;/h2&gt;

&lt;p&gt;In this step we extend the &lt;code&gt;DefaultUrlGenerator&lt;/code&gt; and override the &lt;code&gt;getTemporaryUrl&lt;/code&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace App\Services;

use DateTimeInterface;
use Illuminate\Support\Facades\URL;
use Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator;

class MediaUrlGeneratorService extends DefaultUrlGenerator
{
    public function getTemporaryUrl(DateTimeInterface $expiration, array $options = []): string
    {
        return URL::temporarySignedRoute(
            'private-storage',
            $expiration,
            ['media' =&amp;gt; $this-&amp;gt;media, 'filename' =&amp;gt; $this-&amp;gt;media]
        );
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Replace your URL generator with the default one
&lt;/h2&gt;

&lt;p&gt;Open the &lt;code&gt;config/media-library.php&lt;/code&gt; file and replace the following class with yours.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'url_generator' =&amp;gt; Spatie\MediaLibrary\Support\UrlGenerator\DefaultUrlGenerator::class,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;br&gt;&lt;br&gt;
That's it. Now your local driver does support creating temporary URLs.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
    </item>
    <item>
      <title>An example of using GraphQL in Laravel</title>
      <dc:creator>Daniyal Javani</dc:creator>
      <pubDate>Tue, 21 Apr 2020 07:51:07 +0000</pubDate>
      <link>https://dev.to/daniyaljavani/an-example-of-using-graphql-in-laravel-36h1</link>
      <guid>https://dev.to/daniyaljavani/an-example-of-using-graphql-in-laravel-36h1</guid>
      <description>&lt;p&gt;If you haven't experienced GraphQL in Laravel yet, check out the example&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/Daniyal-Javani/Laravel-GraphQL-Example"&gt;https://github.com/Daniyal-Javani/Laravel-GraphQL-Example&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>graphql</category>
      <category>php</category>
    </item>
  </channel>
</rss>
