<?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: Kotbi Abderrahmane</title>
    <description>The latest articles on DEV Community by Kotbi Abderrahmane (@abdorah).</description>
    <link>https://dev.to/abdorah</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%2F700412%2F7ab6c486-b3b6-4c30-a325-ebaa2b7cd8f2.jpeg</url>
      <title>DEV Community: Kotbi Abderrahmane</title>
      <link>https://dev.to/abdorah</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/abdorah"/>
    <language>en</language>
    <item>
      <title>How to Create a Podcast Using an RSS Feed and Google Podcasts</title>
      <dc:creator>Kotbi Abderrahmane</dc:creator>
      <pubDate>Sun, 12 Mar 2023 20:14:15 +0000</pubDate>
      <link>https://dev.to/abdorah/how-to-create-a-podcast-using-an-rss-feed-and-google-podcasts-17ak</link>
      <guid>https://dev.to/abdorah/how-to-create-a-podcast-using-an-rss-feed-and-google-podcasts-17ak</guid>
      <description>&lt;p&gt;As a frequent listener of audio content, I often find myself jumping between different apps to listen to my favorite podcasts, audiobooks, and other tracks. It can be inconvenient to have a large number of audio files on my phone or in the cloud, especially if I need to download them or be connected to the internet to access them.&lt;/p&gt;

&lt;p&gt;To solve this problem, I decided to create my own podcast using an &lt;code&gt;RSS&lt;/code&gt; feed and Google Podcasts. An &lt;code&gt;RSS&lt;/code&gt; feed is a web feed that allows users and applications to access updates to websites in a standardized format. By creating a hosted audio list in the form of an &lt;code&gt;RSS&lt;/code&gt; feed, I could easily manage my audio content and access it all in one place through Google Podcasts.&lt;/p&gt;

&lt;p&gt;In this article, I'll walk you through the steps to create your own podcast using an &lt;code&gt;RSS&lt;/code&gt; feed and Google Podcasts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: Host Your Audio Files
&lt;/h2&gt;

&lt;p&gt;The first step is to host your audio files in a secure location. I used &lt;code&gt;Firebase&lt;/code&gt; Storage to host my files, but you can use any hosting service that supports direct links to your audio files. To ensure that my files were safe, I added a security rule to my &lt;code&gt;Firebase&lt;/code&gt; bucket that allowed read access but disallowed write access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;rules_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="nx"&gt;service&lt;/span&gt; &lt;span class="nx"&gt;firebase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;b&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="sr"&gt;/o &lt;/span&gt;&lt;span class="err"&gt;{
&lt;/span&gt;    &lt;span class="nx"&gt;match&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;allPaths&lt;/span&gt;&lt;span class="o"&gt;=**&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="na"&gt;read&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Allow anyone to read the files&lt;/span&gt;
      &lt;span class="nx"&gt;allow&lt;/span&gt; &lt;span class="na"&gt;write&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// Do not allow anyone to upload or modify files&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;Once your files are hosted, make note of the direct links to each file. You'll need these links to create your &lt;code&gt;RSS&lt;/code&gt; feed in the next step.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create Your RSS Feed
&lt;/h2&gt;

&lt;p&gt;Next, you'll need to create an &lt;code&gt;RSS&lt;/code&gt; feed that includes the direct links to your audio files. To make this easier, I wrote a Node.js program that creates the&lt;code&gt;RSS&lt;/code&gt; &lt;code&gt;XML&lt;/code&gt; file for me.&lt;/p&gt;

&lt;p&gt;To use this program, save it as a &lt;code&gt;JavaScript&lt;/code&gt; file on your computer and modify the variables at the top of the file to match your own hosting and podcast information. Then, run the program using &lt;code&gt;Node.js&lt;/code&gt; to generate the &lt;code&gt;RSS&lt;/code&gt; &lt;code&gt;XML&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Here's an example of what your final &lt;code&gt;RSS&lt;/code&gt; &lt;code&gt;XML&lt;/code&gt; file might look like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;rss&lt;/span&gt; &lt;span class="na"&gt;xmlns:itunes=&lt;/span&gt;&lt;span class="s"&gt;"http://www.itunes.com/dtds/podcast-1.0.dtd"&lt;/span&gt; &lt;span class="na"&gt;version=&lt;/span&gt;&lt;span class="s"&gt;"2.0"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;channel&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;My Podcast&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;link&amp;gt;&lt;/span&gt;https://example.com/podcast/&lt;span class="nt"&gt;&amp;lt;/link&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;A podcast created using an RSS feed and Google Podcasts&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;language&amp;gt;&lt;/span&gt;en-us&lt;span class="nt"&gt;&amp;lt;/language&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;itunes:author&amp;gt;&lt;/span&gt;My Name&lt;span class="nt"&gt;&amp;lt;/itunes:author&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;itunes:summary&amp;gt;&lt;/span&gt;A podcast created using an RSS feed and Google Podcasts&lt;span class="nt"&gt;&amp;lt;/itunes:summary&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;itunes:image&lt;/span&gt; &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/podcast.jpg"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;itunes:category&lt;/span&gt; &lt;span class="na"&gt;text=&lt;/span&gt;&lt;span class="s"&gt;"Technology"&lt;/span&gt;&lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;itunes:explicit&amp;gt;&lt;/span&gt;no&lt;span class="nt"&gt;&amp;lt;/itunes:explicit&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;item&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;title&amp;gt;&lt;/span&gt;Episode 1: My First Episode&lt;span class="nt"&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;link&amp;gt;&lt;/span&gt;https://example.com/podcast/episode1.mp3&lt;span class="nt"&gt;&amp;lt;/link&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;guid&amp;gt;&lt;/span&gt;https://example.com/podcast/episode1.mp3&lt;span class="nt"&gt;&amp;lt;/guid&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;My first episode of the podcast&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/channel&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/rss&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that we have our &lt;code&gt;RSS&lt;/code&gt; feed ready, we need to publish it. To do that, we need to upload the audio files and the &lt;code&gt;RSS&lt;/code&gt; feed to a server. In this example, we will use &lt;code&gt;Firebase&lt;/code&gt; to host our files.&lt;/p&gt;

&lt;p&gt;Once we have our files uploaded to &lt;code&gt;Firebase&lt;/code&gt; Storage, we can generate the &lt;code&gt;RSS&lt;/code&gt; feed &lt;code&gt;XML&lt;/code&gt; file using &lt;code&gt;Node.js&lt;/code&gt;. We can use a package like &lt;code&gt;rss&lt;/code&gt; to make the process easier. Here's an example code snippet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;RSS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;Storage&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@google-cloud/storage&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Initialize Firebase Storage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Storage&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;projectId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-project-id&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Create a new RSS feed&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;feed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;RSS&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My Podcast&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;A podcast about my favorite things&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;feed_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://my-podcast.com/feed.xml&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;site_url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://my-podcast.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Get a list of all audio files in Firebase Storage&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bucket&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-bucket-name&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getFiles&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Add each audio file to the RSS feed&lt;/span&gt;
&lt;span class="nx"&gt;files&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://storage.googleapis.com/your-bucket-name/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;item&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Listen to this audio track&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;enclosure&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;metadata&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;audio/mpeg&lt;/span&gt;&lt;span class="dl"&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;span class="c1"&gt;// Generate the XML file&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;xml&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we are using the rss package to create a new &lt;code&gt;RSS&lt;/code&gt; feed with a title, description, feed &lt;code&gt;URL&lt;/code&gt;, and site &lt;code&gt;URL&lt;/code&gt;. We then use the &lt;code&gt;@google-cloud/storage&lt;/code&gt; package to get a list of all audio files in our Firebase Storage bucket. For each audio file, we add an item to the &lt;code&gt;RSS&lt;/code&gt; feed with a title, description, &lt;code&gt;URL&lt;/code&gt;, and enclosure (which specifies the audio file &lt;code&gt;URL&lt;/code&gt;, size, and type). Finally, we generate the &lt;code&gt;XML&lt;/code&gt; file using &lt;code&gt;feed.xml()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4reekbv647o08wrivxa0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4reekbv647o08wrivxa0.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once we have our RSS feed &lt;code&gt;XML&lt;/code&gt; file, we can upload it to our server and add it to Google Podcasts. To add our podcast to Google Podcasts, we need to submit our RSS feed &lt;code&gt;UR&lt;/code&gt;L to the Google Podcasts Portal. Once Google verifies our podcast, it will be added to the Google Podcasts directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fid7lw400sux4khzdq4ah.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fid7lw400sux4khzdq4ah.png" alt="podcast"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it! With just a few steps, we have created a podcast and made it available on Google Podcasts. Of course, there are many other things we can do to improve our podcast, such as adding cover art, optimizing the audio quality, and promoting the podcast. But this should give you a good starting point to create your own podcast.&lt;/p&gt;

</description>
      <category>podcast</category>
      <category>node</category>
      <category>rss</category>
    </item>
    <item>
      <title>How to create a production Docker image</title>
      <dc:creator>Kotbi Abderrahmane</dc:creator>
      <pubDate>Sat, 25 Sep 2021 01:17:30 +0000</pubDate>
      <link>https://dev.to/abdorah/how-to-create-production-docker-image-ready-for-deployment-4bbe</link>
      <guid>https://dev.to/abdorah/how-to-create-production-docker-image-ready-for-deployment-4bbe</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In a previous &lt;a href="https://dev.to/abdorah/how-to-build-your-virtual-workspace-84"&gt;article&lt;/a&gt;, I explained how to create a virtual development workspace using &lt;code&gt;Docker&lt;/code&gt;. Thus, I thought that it would be great if I presented a slightly different example using &lt;code&gt;Docker&lt;/code&gt;. In this article, I am going to show you how to create a production &lt;code&gt;Docker&lt;/code&gt; container ready for deployment. To make it interesting, I will work on a &lt;code&gt;JakartaEE&lt;/code&gt;, and &lt;code&gt;MySQL&lt;/code&gt; application. Therefore, you will learn how to build a multiple building stages &lt;code&gt;Docker&lt;/code&gt; image using one single &lt;code&gt;Dockerfile&lt;/code&gt;. Brief, this article aims to teach you and encourage you to learn more about &lt;code&gt;Docker&lt;/code&gt;, because it's a very interesting technology. Maybe in the upcoming articles, I am going to do the exact same using &lt;code&gt;Docker composer&lt;/code&gt; or &lt;code&gt;Docker swarm&lt;/code&gt; (tell me if you are interested in such articles).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  What are we trying to achieve?
&lt;/h3&gt;

&lt;p&gt;First things first, we need a ready-to-use &lt;code&gt;JakartaEE&lt;/code&gt; application. Luckily, I already prepared an application that you can find in this &lt;code&gt;Github&lt;/code&gt; &lt;a href="https://github.com/abdorah/Cabinet_Medical/" rel="noopener noreferrer"&gt;repository&lt;/a&gt;. It is a &lt;code&gt;JakartaEE&lt;/code&gt; application tested on tomcat and requires a &lt;code&gt;MySQL&lt;/code&gt; database. Hence, we need only to create one simple &lt;code&gt;Dockerfile&lt;/code&gt; to get the job done. This last should:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Build the project. As a result, we will get a ready to run &lt;code&gt;.war&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;Set up the &lt;code&gt;.war&lt;/code&gt; produced file for our &lt;code&gt;Tomcat&lt;/code&gt; application server.&lt;/li&gt;
&lt;li&gt;Copy tomcat directory to new &lt;code&gt;Docker&lt;/code&gt; image in which we have our &lt;code&gt;MySQL&lt;/code&gt; database ready to use.&lt;/li&gt;
&lt;li&gt;Run the application!&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That been said, the work on our &lt;strong&gt;single&lt;/strong&gt; &lt;code&gt;Dockerfile&lt;/code&gt; will be divided into two parties. In the first part we are going to work on the first and second step described above (let's call it &lt;code&gt;Tomcat&lt;/code&gt; Side), and in the second part we are going to work on the third step (let's call it &lt;code&gt;MySQL&lt;/code&gt; side). Finally, we will test our application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48schlm5shjedrgheloz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F48schlm5shjedrgheloz.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;Tomcat Side&lt;/code&gt;: Building and deploying the application to &lt;code&gt;Tomcat&lt;/code&gt; application server
&lt;/h3&gt;

&lt;p&gt;The application used in this article relies on the &lt;code&gt;maven&lt;/code&gt; build tool. The simple following command generates the &lt;code&gt;.war&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mvn package
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Firstly, to use &lt;code&gt;Tomcat&lt;/code&gt; you can use the suitable &lt;code&gt;Docker&lt;/code&gt; image from &lt;code&gt;Tomcat&lt;/code&gt; (based on the used &lt;code&gt;Linux&lt;/code&gt; distribution and &lt;code&gt;JDK&lt;/code&gt; version) official page on &lt;a href="https://hub.docker.com/_/tomcat" rel="noopener noreferrer"&gt;&lt;code&gt;DockerHub&lt;/code&gt;&lt;/a&gt;. In this case, I used&lt;code&gt;tomcat:8.5.63-jdk11&lt;/code&gt; and I named &lt;code&gt;TomcatSide&lt;/code&gt;. Surely, we will copy the project files into the &lt;code&gt;Docker&lt;/code&gt; image and install &lt;code&gt;maven&lt;/code&gt; to build the project. After building the project, deploying the application to &lt;code&gt;Tomcat&lt;/code&gt; can be done easily by copying the generated &lt;code&gt;.war&lt;/code&gt; file to &lt;code&gt;tomcat/webapps&lt;/code&gt; directory. You can do this eventually using the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ./target/Cabinet_Medical-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consequently, the &lt;code&gt;Tomcat&lt;/code&gt; side would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create Docker image based on the tomcat:8.5.63-jdk11 base image and name it TomcatSide. &lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;tomcat:8.5.63-jdk11&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="k"&gt;AS&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s"&gt;tomcatside&lt;/span&gt;

&lt;span class="c"&gt;# Set up work directory&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /Cabiner_Medical&lt;/span&gt;

&lt;span class="c"&gt;# Copy the entire project to your Docker image&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . .&lt;/span&gt;

&lt;span class="c"&gt;# Install maven&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt &lt;span class="nb"&gt;install &lt;/span&gt;maven &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    java &lt;span class="nt"&gt;-version&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    mvn &lt;span class="nt"&gt;-version&lt;/span&gt;
&lt;span class="c"&gt;# Build the project&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;mvn package

&lt;span class="c"&gt;# Deploy the .war file to Tomcat server&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ./target/Cabinet_Medical-0.0.1-SNAPSHOT.war /usr/local/tomcat/webapps
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  &lt;code&gt;MySQL Side&lt;/code&gt;: Set up the database and run the application
&lt;/h3&gt;

&lt;p&gt;As you may notice the previous section of this article isn't enough. We need our database! As the first section can be a general example of how to use tomcat in &lt;code&gt;Docker&lt;/code&gt;, this one is a general example too that you can get inspired from to prepare your &lt;code&gt;MySQL&lt;/code&gt; database and run a &lt;code&gt;Tomcat&lt;/code&gt; server in &lt;code&gt;Docker&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Hence, to create a &lt;code&gt;Docker&lt;/code&gt; image with our I used a ready &lt;code&gt;MySQL&lt;/code&gt; server &lt;code&gt;Docker&lt;/code&gt; image from the official &lt;code&gt;MySQL&lt;/code&gt; &lt;a href="https://hub.docker.com/_/mysql" rel="noopener noreferrer"&gt;&lt;code&gt;DockerHub&lt;/code&gt;&lt;/a&gt; container. Next, I set up the root user password, the database name, and the database schema. After that, I copied the &lt;code&gt;/usr/local/tomcat&lt;/code&gt; directory from &lt;code&gt;tomcatside&lt;/code&gt; image to the actual image. The following step is needed only so that we can run &lt;code&gt;Tomcat&lt;/code&gt; server. It consists of installing the appropriate &lt;code&gt;Java&lt;/code&gt; version and getting &lt;code&gt;Tomcat&lt;/code&gt; application server ready for the final step, which is building our production image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; mysql:latest&lt;/span&gt;

&lt;span class="c"&gt;# Set up the password and the database name&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; MYSQL_ROOT_PASSWORD=Strong@Independent1Password&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; MYSQL_DATABASE=bd_cabinetmedicale&lt;/span&gt;

&lt;span class="c"&gt;# Set up the database schema. The following line will result in having a database with tables and content&lt;/span&gt;
&lt;span class="c"&gt;# To avoid any problems you need to make sure that your SQL code works fine.&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt;&lt;span class="s"&gt; ./resources/dataBases.sql /docker-entrypoint-initdb.d&lt;/span&gt;

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/local/tomcat&lt;/span&gt;

&lt;span class="c"&gt;# Copy the tomcat directory from tomcateside to this image&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; --from=tomcatside /usr/local/tomcat /usr/local/tomcat&lt;/span&gt;

&lt;span class="c"&gt;# Set up tomcat, and JDK&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/local/tomcat/webapps&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; CATALINA_BASE=/usr/local/tomcat&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; CATALINA_HOME=/usr/local/tomcat&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; CATALINA_TMPDIR=usr/local/tomcat/temp&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; JRE_HOME=/usr&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; CLASSPATH=/usr/local/tomcat/bin/bootstrap.jar:/usr/local/tomcat/bin/tomcat-juli.jar&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nb"&gt;install &lt;/span&gt;openjdk-11-jdk &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get &lt;span class="nb"&gt;install &lt;/span&gt;ca-certificates-java &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    apt-get clean &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    update-ca-certificates &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    java &lt;span class="nt"&gt;-version&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; JAVA_HOME /usr/lib/jvm/java-11-openjdk&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;export &lt;/span&gt;JAVA_HOME &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;export &lt;/span&gt;CATALINA_BASE &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;export &lt;/span&gt;CATALINA_HOME &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;export &lt;/span&gt;CATALINA_TMPDIR &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;export &lt;/span&gt;JRE_HOME &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nb"&gt;export &lt;/span&gt;CLASSPATH

&lt;span class="c"&gt;# WORKDIR /var/run&lt;/span&gt;

&lt;span class="c"&gt;# RUN cp mysqld/ mysqld.bc -rf&lt;/span&gt;
&lt;span class="c"&gt;# RUN chown mysql:mysql mysqld.bc/&lt;/span&gt;

&lt;span class="k"&gt;EXPOSE&lt;/span&gt;&lt;span class="s"&gt; 8080&lt;/span&gt;

&lt;span class="c"&gt;# Run the application&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /usr/local/tomcat/bin&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x catalina.sh

&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ["/usr/local/tomcat/bin/catalina.sh", "run"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And here it is the final &lt;code&gt;Dockerfile&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuocsxbd881bl075rkzjd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuocsxbd881bl075rkzjd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  One other final step
&lt;/h3&gt;

&lt;p&gt;Congratulations, you created your &lt;code&gt;Dockerfile&lt;/code&gt; you need only the following command to build the &lt;code&gt;Docker&lt;/code&gt; image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker build &lt;span class="nt"&gt;--pull&lt;/span&gt; &lt;span class="nt"&gt;--rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"Dockerfile"&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; cabinetmedical:latest &lt;span class="s2"&gt;"."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also, you need this command to run your container:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"temp"&lt;/span&gt;&lt;span class="nt"&gt;-it&lt;/span&gt;  &lt;span class="nt"&gt;-p&lt;/span&gt; 3306:3306/tcp &lt;span class="nt"&gt;-p&lt;/span&gt; 33060:33060/tcp &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080/tcp cabinetmedical:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And to accede to the container's shell terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;docker &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nt"&gt;-it&lt;/span&gt; temp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrfm98dq9y7f35p0c9h3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrfm98dq9y7f35p0c9h3.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that you completed your &lt;code&gt;Dockerfile&lt;/code&gt;, you can build your image. Probably you will see something like this on your terminal:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00olwoedy4dh4apzaoxd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F00olwoedy4dh4apzaoxd.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;This article is a simple example in which I used docker multiple stages building to create using a single &lt;code&gt;Dockerfile&lt;/code&gt; a production &lt;code&gt;Docker&lt;/code&gt; image. I was excited about this article because often after learning &lt;code&gt;Docker&lt;/code&gt; we use it less in our projects. Instead, we just go to &lt;code&gt;Dockerhub&lt;/code&gt; whenever we need a database image or any kind of image that we need to pull. Don't get me wrong please, I have nothing against that it is totally normal for me. However, you can make more exciting things using docker. That is why I highly encourage you to try to make something similar to what I did in this article in your project.  I hope you enjoyed my article, and thank you!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>java</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to get into the "from your imagination to your screen"  CSS level</title>
      <dc:creator>Kotbi Abderrahmane</dc:creator>
      <pubDate>Fri, 17 Sep 2021 19:13:20 +0000</pubDate>
      <link>https://dev.to/abdorah/how-to-get-into-the-from-your-imagination-to-your-screen-css-level-40l5</link>
      <guid>https://dev.to/abdorah/how-to-get-into-the-from-your-imagination-to-your-screen-css-level-40l5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article aims to help you get better at styling. All along with this article, I will change your understanding to &lt;code&gt;CSS&lt;/code&gt;. Also, open your eyes to the keys that will unlock the next &lt;code&gt;CSS&lt;/code&gt;level for you. However, this article won't be a simple course about &lt;code&gt;CSS&lt;/code&gt;or another motivational speech that you will forget by the end of your reading. So you better practice more and keep your attention on the best practices included in this article.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The styling hidden problems
&lt;/h2&gt;

&lt;p&gt;I believe that the first step to solve an issue is to find it out first. Except that problems are always tricky and tend to remain hidden. And that’s why I wrote this article: to help you find these sneaky problems and get rid of them all.&lt;/p&gt;

&lt;p&gt;The first problem with &lt;code&gt;CSS&lt;/code&gt; is that we often treat styling in the &lt;code&gt;selector property value&lt;/code&gt;. In other words, we ask about the property that will make the exact effect that we want on the page while forgetting that &lt;code&gt;CSS&lt;/code&gt;operates based on the context of the elements of that page. Consequently, we can’t find the answer to all our questions about our styling. Don’t get me wrong please, I am not talking about the &lt;em&gt;how to center a div&lt;/em&gt; kind of questions, but the &lt;em&gt;how to make this animation or this design that I imagined&lt;/em&gt; kind of questions. Nevertheless, the answer isn’t ambiguous at all: the style operates as unites and you won’t find a unique property to achieve what you want. You will need a bench of properties and classes that works together. &lt;strong&gt;And that’s why I believe that styling isn’t just copy-paste process, but also is requires having an analytical mind.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That’s lead us to the second problem, or as I call it: the &lt;em&gt;how to achieve what I imagine?&lt;/em&gt; problem.  While the first problem is about misunderstanding &lt;code&gt;CSS&lt;/code&gt; for a copy-paste with no analytics process, this one is about how to break down the design we have into structures, therefore creating the appropriate style. Because of this problem, we can’t find answers to all our styling questions on google: you can’t browser for example: how to make this element smaller and put it here and make it do this and do that? &lt;strong&gt;That’s why you need to have the ability to turn your complete design into smaller units of style that operate together to create the overall picture.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That been said, the final problem that you may face, is only about memorizing. Indeed, because we often don’t consider the analytical side of &lt;code&gt;CSS&lt;/code&gt; we try to memorize as many properties as we can. Unfortunately, we forget them over time. What is wrong with this is that properties operate together, e.g. you may learn about &lt;code&gt;::after&lt;/code&gt; and &lt;code&gt;::before&lt;/code&gt;, but you will be confused why they don’t work because you don’t know how to use &lt;code&gt;content&lt;/code&gt; with them. &lt;strong&gt;So you don’t need to memorize &lt;code&gt;CSS&lt;/code&gt; rules only, but also how they work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Did make you worry in the first section? Well, don’t feel sad because in the next two sections we will solve these problems together.&lt;/p&gt;

&lt;h2&gt;
  
  
  Long term best practices
&lt;/h2&gt;

&lt;p&gt;The first thing you need to make sure of is to stop reading those bad articles about how you can be better if you learned the basics, read other people’s code and believe in yourself. &lt;strong&gt;You need real solutions!&lt;/strong&gt; &lt;br&gt;
&lt;strong&gt;The first one is to Learn &lt;code&gt;CSS&lt;/code&gt; correctly. You can make styling easier by breaking it down into 4 main parts: Measurement units, Position properties, Forms properties, and colors properties.&lt;/strong&gt; &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Measurement units: are the units that &lt;code&gt;CSS&lt;/code&gt; supports. There are two types generally: absolute and relative units. If you understood how to use them and how to convert from one to another you will be able to give the right size to your elements and to your text.&lt;/li&gt;
&lt;li&gt;Position properties: are the properties used to position elements on the page. Understanding how these properties work is crucial so that you realize your project, and make it responsive. By means of these properties, you will divide your design into layers using &lt;code&gt;z-index&lt;/code&gt;, organize them using grid or flex, or even define their absolute position.&lt;/li&gt;
&lt;li&gt;Boxes properties: are the properties that either surround an element or for the element itself. For example, padding, margin, shadow, transform, keyframes, before, after, content, etc. If you learned how to use these properties you will be able to change the form of elements, add beautiful style to an element, or create animations.&lt;/li&gt;
&lt;li&gt;Color properties: These are the properties related to colors like background color, color, gradient, etc.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;By breaking down the &lt;code&gt;CSS&lt;/code&gt; like above you will be able to ask good questions, and you won’t need to worry about memorizing. Instead, you will look for the exact property that will fulfill your needs.&lt;/p&gt;

&lt;p&gt;Next, you need to learn how to divide your design into sections. This is a very important skill you must acquire. Since it will make your code cleaner by working on every single “component” alone. In fact, this brings up another issue which is that the code becomes missy as it grows up. However, if you make the code organized you won’t face spaghetti code problems like unused style, etc. To solve these issues, &lt;strong&gt;you need to draw on paper your page as it is divided into components. Then think of what position properties you will need to achieve that design, and what measurement units you will need to make it “responsive”. Finally, add the appropriate colors and the box properties to each element.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefpwlm0yw8n9do0h8k18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fefpwlm0yw8n9do0h8k18.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In a nutshell, draw your design into mockups, analyze the design and think of what properties you need, organize your code, and remember to practice so that you can improve and see how effective these practices are.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0x4g8xeyfgktekf4mfm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0x4g8xeyfgktekf4mfm.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Short term tips
&lt;/h2&gt;

&lt;p&gt;In this section, I am going to give you some interesting tools that can improve your productivity.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Google Chrome&lt;/code&gt; inspect flex/ grid/ transform/ fonts / animations / box-shadow/ margin...:
Using these tools you will be able to work with these properties easily. You just need to add into your &lt;code&gt;CSS&lt;/code&gt; class for example:&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9d1adcd5e3zuzrutpmk2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9d1adcd5e3zuzrutpmk2.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7mxwipyilyliuxzhbbh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa7mxwipyilyliuxzhbbh.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.my-class&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;grid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c"&gt;/* or display: flex;*/&lt;/span&gt;
   &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;leftrotation&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nc"&gt;.my-other-class&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;box-shadow&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnmlrpv5dqmsv4j9luj9i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnmlrpv5dqmsv4j9luj9i.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fypupcrmoawuh8zo1y4pl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fypupcrmoawuh8zo1y4pl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To use animations section type &lt;code&gt;Ctl+Shift+p&lt;/code&gt; and then look for animations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@keyframes&lt;/span&gt; &lt;span class="n"&gt;leftrotation&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
 &lt;span class="err"&gt;100&lt;/span&gt;&lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="nl"&gt;transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;rotate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;315deg&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;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdswrg26jedyvm76hhq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzdswrg26jedyvm76hhq8.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpufrriu27odvj0v267x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdpufrriu27odvj0v267x.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Google Chrome&lt;/code&gt; style inspect and experimental &lt;code&gt;CSS OverView&lt;/code&gt; feature:
These features allows you to capture &lt;code&gt;CSS&lt;/code&gt; of the website and check the colors and the fonts used, in addition to the unused style declarations and the media queries. You can check the entire website style.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs8thonbhhy0lrxa5ux7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbs8thonbhhy0lrxa5ux7.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To activate &lt;code&gt;CSS OverView&lt;/code&gt;, go to settings by opening your inspect tools and then press &lt;code&gt;F1&lt;/code&gt; to get into settings. Then look for &lt;code&gt;CSS OverView&lt;/code&gt; in the Experiments section. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;VSCode&lt;/code&gt; extensions: If you use Visual Studio Code,you already know about how these extensions can make your life easier. So I am going to share with you a small collection of those:&lt;/li&gt;
&lt;li&gt;Auto Close Tag + Auto Rename Tag &lt;/li&gt;
&lt;li&gt;JavaScript (ES6) code snippets + ESLint&lt;/li&gt;
&lt;li&gt;Prettier-Code Formatter&lt;/li&gt;
&lt;li&gt;Color Highlight&lt;/li&gt;
&lt;li&gt;Live Server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrxjo75grnkj6b2d2e3a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxrxjo75grnkj6b2d2e3a.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;I hope you enjoyed reading this article. In this conclusion I want to ask you if you have any addition related to this topic. I would love to read about some exciting methods and tools that can improve my productivity. &lt;/p&gt;

</description>
      <category>vscode</category>
      <category>css</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>How to build your virtual workspace</title>
      <dc:creator>Kotbi Abderrahmane</dc:creator>
      <pubDate>Sat, 11 Sep 2021 18:04:56 +0000</pubDate>
      <link>https://dev.to/abdorah/how-to-build-your-virtual-workspace-84</link>
      <guid>https://dev.to/abdorah/how-to-build-your-virtual-workspace-84</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;In this article I will teach how  to use &lt;code&gt;Docker&lt;/code&gt; containers as a development workspace using a real word example. I will go through multiple &lt;code&gt;Dev Ops&lt;/code&gt; related topics. However, this is still an example that I have had the opportunity to work on during my open-sourcing journey.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  What do we want to achieve?
&lt;/h2&gt;

&lt;p&gt;One of the wonderful open source projects that I have got the opportunity to help in is &lt;a href="https://github.com/One-Language" rel="noopener noreferrer"&gt;&lt;strong&gt;the One Programming language&lt;/strong&gt;&lt;/a&gt; . The goal of this project is to create a programming language named &lt;strong&gt;One&lt;/strong&gt;. To build the project and run tests you must have a list of hard to install and configure dependencies on your machine, e.g. &lt;code&gt;Make&lt;/code&gt;, &lt;code&gt;LLVM&lt;/code&gt;, etc. Moreover, we wanted to make it easy for developers to get involved and contribute easily in the project. That's why we considered having a docker image to build the code and run tests as priority. Hence, we created this beautiful &lt;a href="https://hub.docker.com/r/onelangorg/one" rel="noopener noreferrer"&gt;image&lt;/a&gt; for our organization. &lt;/p&gt;

&lt;p&gt;In this article I am going to show you how we made it and also how you can make you own development image. &lt;/p&gt;

&lt;h2&gt;
  
  
  Build the &lt;code&gt;Docker&lt;/code&gt; image
&lt;/h2&gt;

&lt;p&gt;First things first, we need to build the image. Indeed there is nothing special in this section, because we will only write a &lt;a href="https://github.com/One-Language/One/blob/master/Dockerfile" rel="noopener noreferrer"&gt;&lt;code&gt;Dockerfile&lt;/code&gt;&lt;/a&gt; for our image. Yet, what make this image special are the pieces of software that will include. Generally, you ought to setup packages required to run your project and your tests, along side with a version control system like &lt;code&gt;git&lt;/code&gt;. As far as I am concerned, I included the following packages in my lightweight &lt;code&gt;alpine&lt;/code&gt; base image:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;FROM&lt;/span&gt;&lt;span class="s"&gt; alpine:latest&lt;/span&gt;
&lt;span class="k"&gt;LABEL&lt;/span&gt;&lt;span class="s"&gt; The One Programming Language&lt;/span&gt;

&lt;span class="c"&gt;# LLVM version&lt;/span&gt;
&lt;span class="k"&gt;ARG&lt;/span&gt;&lt;span class="s"&gt; LLVM_VERSION=12.0.1&lt;/span&gt;

&lt;span class="c"&gt;# LLVM dependencies&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;apk &lt;span class="nt"&gt;--no-cache&lt;/span&gt; add &lt;span class="se"&gt;\
&lt;/span&gt;    autoconf &lt;span class="se"&gt;\
&lt;/span&gt;    automake &lt;span class="se"&gt;\
&lt;/span&gt;    cmake &lt;span class="se"&gt;\
&lt;/span&gt;    freetype-dev &lt;span class="se"&gt;\
&lt;/span&gt;    g++ &lt;span class="se"&gt;\
&lt;/span&gt;    gcc &lt;span class="se"&gt;\
&lt;/span&gt;    libxml2-dev &lt;span class="se"&gt;\
&lt;/span&gt;    linux-headers &lt;span class="se"&gt;\
&lt;/span&gt;    make &lt;span class="se"&gt;\
&lt;/span&gt;    musl-dev &lt;span class="se"&gt;\
&lt;/span&gt;    ncurses-dev &lt;span class="se"&gt;\
&lt;/span&gt;    python3 py3-pip &lt;span class="se"&gt;\
&lt;/span&gt;    git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next I setup the reaming packages, like &lt;code&gt;LLVM&lt;/code&gt; and &lt;code&gt;pre-commit&lt;/code&gt;. This last is a powerful framework for managing and maintaining multi-language &lt;code&gt;pre-commit&lt;/code&gt; hooks. It is an important addition to your open source project. Since &lt;code&gt;Git hook&lt;/code&gt; scripts are useful for identifying simple issues before submission to code review. We run our hooks on every commit to automatically point out issues in code such as missing semicolons, trailing whitespace, and debug statements. By pointing these issues out before code review, this allows a code reviewer to focus on the architecture of a change while not wasting time with trivial style nitpicks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Build and install LLVM&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;wget &lt;span class="s2"&gt;"https://github.com/llvm/llvm-project/archive/llvmorg-&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LLVM_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Error downloading LLVM version ${LLVM_VERSION}'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;tar &lt;/span&gt;zxf llvmorg-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LLVM_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;.tar.gz &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm &lt;/span&gt;llvmorg-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LLVM_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;.tar.gz

&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;cd &lt;/span&gt;llvm-project-llvmorg-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LLVM_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;mkdir &lt;/span&gt;build

&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt;  /llvm-project-llvmorg-${LLVM_VERSION}/build&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;cmake ../llvm &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="s2"&gt;"Unix Makefiles"&lt;/span&gt; &lt;span class="nt"&gt;-DLLVM_TARGETS_TO_BUILD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"X86"&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;-DLLVM_ENABLE_PROJECTS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"clang;lld"&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="nt"&gt;-DCMAKE_BUILD_TYPE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MinSizeRel &lt;span class="se"&gt;\
&lt;/span&gt;    &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Error running CMake for LLVM'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;RUN &lt;/span&gt;make &lt;span class="nt"&gt;-j&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;nproc&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Error building LLVM'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;make &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'Error installing LLVM'&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;exit &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ../.. &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; llvm-project-llvmorg-&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;LLVM_VERSION&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; CXX=clang++&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; CC=clang&lt;/span&gt;

&lt;span class="c"&gt;# pre-commit installation&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pre-commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now as everything is perfectly configured, you can copy your project directory, build the code, and run your tests while showing significant logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="c"&gt;# Work directory setup&lt;/span&gt;
&lt;span class="k"&gt;COPY&lt;/span&gt;&lt;span class="s"&gt; . /One&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /One&lt;/span&gt;

&lt;span class="c"&gt;# CMake configuration &amp;amp; building&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;mkdir &lt;/span&gt;build
&lt;span class="k"&gt;RUN &lt;/span&gt;cmake &lt;span class="nt"&gt;--no-warn-unused-cli&lt;/span&gt; &lt;span class="nt"&gt;-DCMAKE_EXPORT_COMPILE_COMMANDS&lt;/span&gt;:BOOL&lt;span class="o"&gt;=&lt;/span&gt;TRUE &lt;span class="nt"&gt;-DCMAKE_BUILD_TYPE&lt;/span&gt;:STRING&lt;span class="o"&gt;=&lt;/span&gt;Debug &lt;span class="nt"&gt;-DCMAKE_C_COMPILER&lt;/span&gt;:FILEPATH&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/gcc &lt;span class="nt"&gt;-DCMAKE_CXX_COMPILER&lt;/span&gt;:FILEPATH&lt;span class="o"&gt;=&lt;/span&gt;/usr/bin/g++ &lt;span class="nt"&gt;-H&lt;/span&gt;/One &lt;span class="nt"&gt;-B&lt;/span&gt;/One/build &lt;span class="nt"&gt;-G&lt;/span&gt; &lt;span class="s2"&gt;"Unix Makefiles"&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;cmake &lt;span class="nt"&gt;--build&lt;/span&gt; ./build &lt;span class="nt"&gt;--config&lt;/span&gt; Debug &lt;span class="nt"&gt;--target&lt;/span&gt; all &lt;span class="nt"&gt;-j&lt;/span&gt; 6 &lt;span class="nt"&gt;--&lt;/span&gt;

&lt;span class="c"&gt;# Change directory to build&lt;/span&gt;
&lt;span class="k"&gt;WORKDIR&lt;/span&gt;&lt;span class="s"&gt; /One/build&lt;/span&gt;

&lt;span class="c"&gt;# Running example input.one&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;./lexer ../src/input.one log
&lt;span class="k"&gt;RUN &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;log

&lt;span class="c"&gt;# Running tests&lt;/span&gt;
&lt;span class="k"&gt;RUN &lt;/span&gt;./lexer_test
&lt;span class="k"&gt;RUN &lt;/span&gt;./parser_test
&lt;span class="k"&gt;RUN &lt;/span&gt;./argument_test

&lt;span class="c"&gt;# Tests Dashboard&lt;/span&gt;
&lt;span class="k"&gt;CMD&lt;/span&gt;&lt;span class="s"&gt; ctest --output-on-failure&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Deploy it to &lt;code&gt;DockerHub&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To do so, you will need a &lt;code&gt;DockerHub&lt;/code&gt; account. Yet, only your account username and credentials are required. As we are going to deploy it using &lt;code&gt;GitHub Actions&lt;/code&gt;. Similarly to &lt;code&gt;pre-commit&lt;/code&gt;, using &lt;code&gt;GitHub Actions&lt;/code&gt;, or any &lt;code&gt;CI\CD&lt;/code&gt; tool is a good &lt;code&gt;Dev Ops&lt;/code&gt; practice. Especially that we are going to configure our image to run &lt;code&gt;pre-commit&lt;/code&gt; hooks, build the code, run tests, and deploy it the new image to &lt;code&gt;DockerHub&lt;/code&gt;. In fact, you will do very minor changes to the following &lt;a href="https://github.com/One-Language/One/blob/master/.github/workflows/docker-image.yml" rel="noopener noreferrer"&gt;&lt;code&gt;GitHub Workflow&lt;/code&gt;&lt;/a&gt; to use it in any other project.&lt;/p&gt;

&lt;p&gt;Let's begging by configuring the &lt;code&gt;GitHub Workflow&lt;/code&gt; that will run on every push or pull request:&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;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Dockerize One Programming language&lt;/span&gt;

&lt;span class="na"&gt;on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;push&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;master&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;pull_request&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;branches&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;master&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build-deploy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Publish Docker image&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next, we will add steps to configure needed &lt;code&gt;GitHub Actions&lt;/code&gt; to deploy to &lt;code&gt;DockerHub&lt;/code&gt;. Particularly, you won't need any other &lt;code&gt;GitHub Actions&lt;/code&gt;. Because, you already have a &lt;code&gt;Dockerfile&lt;/code&gt; with all the prerequisites!&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;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Checkout code&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up QEMU&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/setup-qemu-action@v1&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Set up Docker Buildx&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/setup-buildx-action@v1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We shall continue by Sign into our &lt;code&gt;DockerHub&lt;/code&gt; account:&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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Login to DockerHub&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/login-action@v1&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;username&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.DOCKER_HUB_USERNAME}}&lt;/span&gt;
          &lt;span class="na"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{secrets.DOCKER_HUB_PASSWORD}}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we go to the next step you need to add &lt;code&gt;secrets.DOCKER_HUB_USERNAME&lt;/code&gt; and &lt;code&gt;secrets.DOCKER_HUB_PASSWORD&lt;/code&gt; to your &lt;code&gt;Github&lt;/code&gt; repository:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwufx6cnb9h344tlppzs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwufx6cnb9h344tlppzs.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, publish your new image named &lt;code&gt;onelangorg/one:latest&lt;/code&gt; to &lt;code&gt;DockerHub&lt;/code&gt;:&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="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Build and Push to DockerHub&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;docker/build-push-action@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
          &lt;span class="na"&gt;push&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;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;onelangorg/one:latest&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Don't forget to configure cache so that you won't need to go with all the unnecessary configuration steps everytime. Also, this will decrease the run time dramatically. In my case without cache the run time is about two hours, but with cache it often doesn't surpass one minute and a half!&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;cache-from&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;type=registry,ref=onelangorg/one:latest&lt;/span&gt;
          &lt;span class="na"&gt;cache-to&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;type=inline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consequently, you will cerate a &lt;code&gt;Docker&lt;/code&gt; &lt;a href="https://hub.docker.com/r/onelangorg/one" rel="noopener noreferrer"&gt;repository&lt;/a&gt; in your docker account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Use it as a Workspace
&lt;/h2&gt;

&lt;p&gt;In this section you will need to pull the &lt;code&gt;docker&lt;/code&gt; image form &lt;code&gt;DockerHube&lt;/code&gt; have &lt;code&gt;VSCode&lt;/code&gt; with &lt;code&gt;Remote-Containers&lt;/code&gt; installed:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felmj46w3491kbqx3df54.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Felmj46w3491kbqx3df54.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This awesome extension admit of getting into the &lt;code&gt;Docker&lt;/code&gt; container itself, by opening a &lt;code&gt;VSCode&lt;/code&gt; window inside it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmmzpd6mgy2a35pxf5fy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftmmzpd6mgy2a35pxf5fy.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After Opening the new window attached to your container you can open the development directory:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhnitytlgeoy3v8j9yql.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frhnitytlgeoy3v8j9yql.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And Here you go you have a workspace configured and ready to use!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa5j8jg8wnkaooq4giyfo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fa5j8jg8wnkaooq4giyfo.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Now that you come to the end of this article, you can see how important to use &lt;code&gt;Docker&lt;/code&gt;, &lt;code&gt;DockerHub&lt;/code&gt;, and &lt;code&gt;GitHub Actions&lt;/code&gt;. As well as how easy to use are they. These technologies helps developers to be more productive and not bother with the repetitive configuration of the workspace. On every pull request, we get an updated &lt;code&gt;Docker&lt;/code&gt; image with a clean code and successfully run tests thanks to &lt;code&gt;pre-commit&lt;/code&gt;, &lt;code&gt;Github Actions&lt;/code&gt;, and cache.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>github</category>
      <category>vscode</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Java Functional Programming</title>
      <dc:creator>Kotbi Abderrahmane</dc:creator>
      <pubDate>Tue, 07 Sep 2021 11:56:27 +0000</pubDate>
      <link>https://dev.to/abdorah/java-functional-programming-57gd</link>
      <guid>https://dev.to/abdorah/java-functional-programming-57gd</guid>
      <description>&lt;p&gt;&lt;em&gt;This article will take you to the next level in java. Are you ready!&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;This article is basically a set of examples of multiple tools provided by Java 8. Those tools have helped to make programming way more easier and optimal(even in terms of hardware resources), using a declarative approach. Hence, we don't have to tell many details, but only what we want to achieve by our code. I should highlight also the fact that this pack of tools is something that a java developer &lt;em&gt;"must"&lt;/em&gt; know.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Map
&lt;/h3&gt;

&lt;p&gt;1) Stream:&lt;/p&gt;

&lt;p&gt;In this section we will dive into the world of streams. We will understand them, how they work, and why we need them in the first place.&lt;br&gt;
2) Lazy expressions:&lt;/p&gt;

&lt;p&gt;By learning more about lazy expressions and precisely lambdas and references in this section you will be able to make your code so lazy. Also will make the use of your hardware optimal.&lt;br&gt;
3) Functional interfaces:&lt;/p&gt;

&lt;p&gt;This is actually the main section in which you will be able to see real example of the implementation of code and you will understand how to use all what you have learnt. Still more concrete examples will be in the last section.&lt;br&gt;
4) Optional:&lt;/p&gt;

&lt;p&gt;This brief section will take you back to bad memory of your first steps learning java, and exactly to the scary &lt;code&gt;NullPointerException&lt;/code&gt;. But, this time you will be able to take control over every thing with no worries of any unpredictable null value problems.&lt;/p&gt;

&lt;p&gt;Finally, you will work on real examples and learn some specific tricks that will alter your programming style to the best!&lt;/p&gt;

&lt;p&gt;To understand exactly why I choose to follow this planing You need to understand the relation between those parts. Because, this selection of topics doesn't recover every thing about java and functional programming. Still, it will be your main support to learn more.&lt;/p&gt;


&lt;h2&gt;
  
  
  1) Java 8 Stream API
&lt;/h2&gt;

&lt;p&gt;Java 8 Stream is a sequence of elements from certain source, on which we can perform basic aggregate operations. This source can be a collection, array or a stream - this is called &lt;em&gt;pip-lining&lt;/em&gt;. In contrast to collections, streams aren't data structure. They allow to extract the required value only when we need it. Also they support lazy evaluation and were initially created to be used with lambdas(refer to the second part). They are contained under the package java.util.stream. There is a very large set of operations to perform on a stream. The majority of them return a stream so that we can perform more operations. Moreover streams don't store data nor changes. They just perform iteration internally once and then return a result. So we say that they are &lt;strong&gt;consumable and functional in nature&lt;/strong&gt;. One more powerful point for stream is that they are possibly unbounded (unlimited, so we don't have to precis a certain size for a stream). Thus, you can perform operations on the first and last elements of a stream with no worries for its size or the order of elements because they also keep the same order of elements as the source.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This article will just give some important and highly used examples of functions and operations. If you were looking for more operations that java offers, you can look for them &lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html"&gt;here&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In a nutshell:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Collection&lt;/th&gt;
&lt;th&gt;Stream&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;under the java.util package&lt;/td&gt;
&lt;td&gt;under the java.util.stream package&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;in memory data structure&lt;/td&gt;
&lt;td&gt;only for processing data&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;all values must be computed then stored (eager)&lt;/td&gt;
&lt;td&gt;allow operations on only the required values (lazy)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;we can perform operations as much as we want on collection&lt;/td&gt;
&lt;td&gt;the elements of a stream are only visited once during the life of a stream (if you want to visit them again use an other stream!)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;must have certain size&lt;/td&gt;
&lt;td&gt;doesn't need a fixed size. Yet, we can get the first/last elements&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In the next example we gonna use the following import:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;import java.util.List;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you take this list of friends:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;String&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;friends&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;List&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Mohamed"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Abderrahmane"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Ajar"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Omar"&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt;&lt;span class="s"&gt;"Youssef"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Imagine we want to print the length of each name. Normally, your code would be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;];&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;friends&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think this code is clear for you. But other method to do the same thing with no need to declare any variable is the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;friends&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;&lt;span class="c1"&gt;//create stream of friends&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;()));&lt;/span&gt;&lt;span class="c1"&gt;//Then print successively each one of them&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Please refer to the next section to understand what are these expressions: &lt;code&gt;t -&amp;gt; expression&lt;/code&gt;&lt;/em&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  2) Lazy expressions
&lt;/h2&gt;

&lt;p&gt;Lazy expressions or lazy evaluation is a strategy of coding and also a mindset. You will find a lot of complex explanations to what exactly a lazy evaluation is. Yet, it is all about how to make your code &lt;strong&gt;lazier&lt;/strong&gt;, and by this I mean &lt;strong&gt;optimal&lt;/strong&gt;. This could be done by postpone the execution of a function until we really need it be executed. Java is lazy when it comes to the evaluation of logical arguments,e.g. in &lt;code&gt;f1() || f2()&lt;/code&gt; , the call of &lt;code&gt;f2()&lt;/code&gt; is never performed if &lt;code&gt;f1()&lt;/code&gt; returns a boolean true. Still, a method is executed as soon as it is called. On the other hand, if a lazy method wasn't called, then it will just lay around whithout doing anything. However, we are often tempted towards writing a code which is executed eagerly, because it is easy to write and to understand the logic behind it. But sometimes it is just a waste of time and hardware resources if a method doesn't use all the passed arguments. In this section we gonna focus exclusively on lambdas, method reference, and how they make your code lazier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Method reference&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Method reference refers to a method from class or object using &lt;code&gt;class::methodName&lt;/code&gt; type syntax. There is different types of available method references in java 8. For example:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Explanation&lt;/th&gt;
&lt;th&gt;Form&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Reference to static method&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Class::staticMethodName&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Math::max equivalent to Math.max(x,y)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reference to instance method from instance&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;ClassInstance::instanceMethodName&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;System.out::println equivalent to System.out.println(x)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reference to instance method from class type&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Class::instanceMethodName&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;String::length equivalent to str.length()&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reference to constructor&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Class::new&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;ArrayList::new equivalent to new ArrayList()&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Lambda expression&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lambda expression are also called anonymous function, i.e., a function with no name and any identifier.&lt;br&gt;
They are nameless functions given as constant values, and written exactly in the place where it’s needed, typically as a parameter to some other function. They are writing in this form:&lt;code&gt;(parameters) -&amp;gt; expression&lt;/code&gt;; which means that &lt;code&gt;expression&lt;/code&gt; is preformed when it is called, on the value that takes the variables &lt;code&gt;parameters&lt;/code&gt;.( For example, this expression &lt;code&gt;(x, y) -&amp;gt; x + y&lt;/code&gt; returns the result of the addition of &lt;code&gt;x&lt;/code&gt; and &lt;code&gt;y&lt;/code&gt;, also this expression &lt;code&gt;(x) -&amp;gt; System.out.println(x)&lt;/code&gt; prints the value given to the argument &lt;code&gt;x&lt;/code&gt;;&lt;/p&gt;

&lt;p&gt;In the example above &lt;code&gt;.forEach(n-&amp;gt;System.out.println( n.length()));&lt;/code&gt; means that we gonna perform the action between brackets on each element of our stream, which is to print them one by one.&lt;/p&gt;

&lt;p&gt;Moreover, the code above also can be written as following with some small changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="n"&gt;friends&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;map&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;String:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="n"&gt;length&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="c1"&gt;//Map each name to its length. As result we get a stream of lengths.&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//Print each element of the stream.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  3) Functional interfaces
&lt;/h2&gt;

&lt;p&gt;It's time to dive more in one of the main innovations that java 8 has come with.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Overall, Functional interfaces are interfaces that permit exactly one abstract method inside them, in addition to as many as you like of default methods. Since they are not abstract because they have an implementation (I should also highlight the fact that default functions are a revolutionary addition in java 8). Functional interfaces are also named &lt;strong&gt;Single Abstract Method interfaces *(SAM Interfaces)&lt;/strong&gt;*. In Java 8, functional interfaces can be represented using lambda expressions, method reference and constructor references as well. It is optional to add &lt;code&gt;@FunctionalInterface&lt;/code&gt; annotation to a functional interface to define one. For example we can have something like this:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="nd"&gt;@FunctionalInterface&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;MyInterface&lt;/span&gt; 
&lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;job&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;&lt;span class="c1"&gt;//one abstract method&lt;/span&gt;
&lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fct1&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;&lt;span class="c1"&gt;//default method&lt;/span&gt;
&lt;span class="c1"&gt;//Method body&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fct2&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;&lt;span class="c1"&gt;//default method&lt;/span&gt;
&lt;span class="c1"&gt;//Method body&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;fct&lt;/span&gt;&lt;span class="o"&gt;(){&lt;/span&gt;&lt;span class="c1"&gt;//default static method&lt;/span&gt;
&lt;span class="c1"&gt;//Method body&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Default methods are a related topic. Since, they are methods that can have an implementation into an interface! This implementation by default can be either kept as it is, or overridden. We can make a default method by adding the keyword &lt;code&gt;default&lt;/code&gt; or, and this is so cool, by making it &lt;code&gt;static&lt;/code&gt; with no need to add the &lt;code&gt;default&lt;/code&gt; keyword. I won't dive into more details that you can look for later(believe me this new feature is awesome so please check the references), but a good question to ask is what also they provide so that I putted them into this section? &lt;strong&gt;Well, because default methods enable the lambdas functionality in java.&lt;/strong&gt; Take a look to this example from &lt;code&gt;java.lang.Iterable&lt;/code&gt;:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="c1"&gt;//This method allow you to perform action on collection&lt;/span&gt;
&lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Consumer&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;?&lt;/span&gt; &lt;span class="kd"&gt;super&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="nc"&gt;Objects&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;requireNonNull&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="no"&gt;T&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt; &lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="n"&gt;action&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;accept&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="cm"&gt;/*
Before java 8 you have to iterate on your collection using the loop for. But now you can do something like this (I reused the first example here):
*/&lt;/span&gt;
&lt;span class="n"&gt;friends&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;println&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;&lt;span class="c1"&gt;//to print all the friends names.&lt;/span&gt;
&lt;span class="c1"&gt;//Or;&lt;/span&gt;
&lt;span class="n"&gt;friends&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;forEach&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;f&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Also, &lt;code&gt;java.util&lt;/code&gt; has a set of pre-implimented functional interfaces like the following examples:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Functional interface&lt;/th&gt;
&lt;th&gt;Definition&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Function &amp;lt; TypeOfInput,TypeOfReturn&amp;gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Represents a function that accepts one argument and produces a result.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consumer &amp;lt; TypeOfInput&amp;gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Represents an operation that accepts a single input argument and returns no result.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Supplier&amp;lt; TypeOfInput&amp;gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Represents a supplier of results.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Predicate&amp;lt; TypeOfInput&amp;gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Represents a predicate (boolean-valued function) of one argument.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;I will just give an exhaustive example of implementation of a &lt;code&gt;function&lt;/code&gt;. Everything else goes the same way. Yet, if you want the full list you can check the provided documentation of &lt;em&gt;&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html"&gt;Oracle&lt;/a&gt;&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;&lt;span class="cm"&gt;/*
This example represente a method that increment its int argument by one.
*/&lt;/span&gt;

&lt;span class="c1"&gt;//It would be something like this:&lt;/span&gt;
&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="nf"&gt;increment&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="cm"&gt;/*
With functional interface "Function" it becomes:
Don't forget to import:
import java.util.function.Function;
*/&lt;/span&gt;
&lt;span class="nc"&gt;Function&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Integer&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;increment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want more easy examples for this topic you can check my github &lt;a href="https://github.com/abdorah/java_functional_programming"&gt;repository&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  4) Optional
&lt;/h2&gt;

&lt;p&gt;When I was a 'newbie' to java I hated it because of one scary exception that keeps popping up on my screen: The java famous &lt;code&gt;NullPointerException&lt;/code&gt;. To be honest it was because some stupid, missed yet required initial values, so java is not the one to blame here. Later, I learnt about the class &lt;code&gt;Optional&lt;/code&gt; of the package &lt;code&gt;java.util&lt;/code&gt;. Optional, is in fact a value that can be null or not null. You have a huge set of tools and methods to manipulate it. If it was &lt;em&gt;present&lt;/em&gt;, if you want to &lt;em&gt;throw&lt;/em&gt; a specific exception, if you want to &lt;em&gt;get&lt;/em&gt; the value, &lt;em&gt;or else&lt;/em&gt; you have methods to do so in this class.&lt;/p&gt;

&lt;p&gt;So let us go directly to see some examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight java"&gt;&lt;code&gt;
&lt;span class="cm"&gt;/*In all the example you can change the value 'null' and the SomeUserCostumizedOrAnyException by something else.
*/&lt;/span&gt;

&lt;span class="cm"&gt;/*
If you want to print a value when only it is present.
*/&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseGet&lt;/span&gt;&lt;span class="o"&gt;(()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;"value to show by default"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="cm"&gt;/*
If you want to print a value when only it is present, or just throw an exception.
*/&lt;/span&gt;

&lt;span class="c1"&gt;// method reference&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nl"&gt;SomeUserCostumizedOrAnyException:&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;//Lambda&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
   &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;orElseThrow&lt;/span&gt;&lt;span class="o"&gt;(()-&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;SomeUserCostumizedOrAnyException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"the default value is missed"&lt;/span&gt;&lt;span class="o"&gt;)));&lt;/span&gt;
&lt;span class="cm"&gt;/*
If you want to check of the value is present and then print the String email(you have first change null by something like this "xyz@example.com")
*/&lt;/span&gt;

&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;ifPresentOrElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Sending email to "&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="s"&gt;"."&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"Cannot send emails!"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="cm"&gt;/*
A last comparison, in case of you want to just get the value.
*/&lt;/span&gt;

&lt;span class="c1"&gt;//normal method(imperative approach in which you declare all your variables and explicitly the logic of how to get the wanted result)&lt;/span&gt;
&lt;span class="nc"&gt;String&lt;/span&gt; &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"present value"&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;){&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"s is null"&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;//new method with Optional (declarative approach in which you just describe what you want as result exactly)&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;ofNullable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"present value"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;orElse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"s is null"&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;

&lt;span class="c1"&gt;//Or just simply&lt;/span&gt;
&lt;span class="nc"&gt;System&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;out&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;println&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Optional&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;of&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"present value"&lt;/span&gt;&lt;span class="o"&gt;).&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;());&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;The main goal of this article was to teach you about declarative approach of programming in java. I hope I achieved this goal! But before to wrap up, I just want to remind you of the fact that this should serve as an opening and the given article and examples shouldn't be the last thing you see. So, please keep practicing to learn.&lt;/p&gt;

&lt;p&gt;In this article you learnt:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Section&lt;/th&gt;
&lt;th&gt;Importance&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Streams&lt;/td&gt;
&lt;td&gt;Streams make your code lazy by only using the required values in a data source. To do so, you have a powerful set of aggregate methods to use&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lazy expressions&lt;/td&gt;
&lt;td&gt;Lambdas and method reference change your coding style to be more declarative and also lazier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Functional Interfaces&lt;/td&gt;
&lt;td&gt;This part serves as the theory behind functional programming in java and some good examples to understand it.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Optional&lt;/td&gt;
&lt;td&gt;This class works lot with streams and functional interfaces, in case of null values. It will allow you to avoid the struggle of facing the &lt;code&gt;NullPointerException&lt;/code&gt; every time you execute your code.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;




&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://howtodoinjava.com/java-8-tutorial/"&gt;HowToDoInJava&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Oracle Documentation:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/function/package-summary.html"&gt;Function&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html"&gt;Stream&lt;/a&gt;&lt;/p&gt;

</description>
      <category>java</category>
      <category>functional</category>
    </item>
  </channel>
</rss>
