<?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: Victor Garcia Dev</title>
    <description>The latest articles on DEV Community by Victor Garcia Dev (@victorgarciadev).</description>
    <link>https://dev.to/victorgarciadev</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%2F408717%2F002af1a5-9a8d-4e8c-9928-c8b1689e87da.png</url>
      <title>DEV Community: Victor Garcia Dev</title>
      <link>https://dev.to/victorgarciadev</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/victorgarciadev"/>
    <language>en</language>
    <item>
      <title>How to Dockerize a React App and Deploy It Easily</title>
      <dc:creator>Victor Garcia Dev</dc:creator>
      <pubDate>Wed, 01 Nov 2023 14:28:22 +0000</pubDate>
      <link>https://dev.to/victorgarciadev/how-to-dockerize-a-react-app-and-deploy-it-easily-1kp</link>
      <guid>https://dev.to/victorgarciadev/how-to-dockerize-a-react-app-and-deploy-it-easily-1kp</guid>
      <description>&lt;p&gt;Do you want to learn how to dockerize a React app and make it ready for deployment? In this article, I´ll show you how to do that with a practical example from my &lt;a href="https://github.com/victorgrubio/blog-projects/tree/main/react-nginx-dockerization"&gt;GitHub repo&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Originally published at MentorCruise: &lt;a href="https://mentorcruise.com/blog/how-to-dockerize-a-react-app-and-deploy-it-easily/"&gt;How to Dockerize a React App and Deploy It Easily - MentorCruise&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Prerequisites&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Ensure you have a foundational understanding of React, Docker, and basic shell scripting. Ensure Docker and Node.js are installed on your machine, and you have a code editor ready for some hands-on action!&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Understanding the React Application Structure&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The React application in our repository is structured with various components, dependencies, and configurations. The app is a simple goal tracker that lets you add, edit, and delete your goals. It uses React Hooks, React Router, and Axios to create a dynamic and interactive UI. The app also communicates with a backend API that uses MongoDB as the database. The apps structure is as follows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;package.json&lt;/code&gt;: This file defines the dependencies and scripts for the app. We use libraries such as react, react-dom, react-router-dom, axios, and bootstrap.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/index.js&lt;/code&gt;: This file renders the main App component and wraps it with a BrowserRouter component to enable routing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/App.js&lt;/code&gt;: This file defines the App component, which contains the main layout and logic of the app. It uses useState and useEffect hooks to manage the state and fetch data from the API. It also uses Switch and Route components to render different pages based on the URL path.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/components&lt;/code&gt;: This directory contains the reusable components for the app, such as GoalList, GoalForm, GoalItem, Navbar, and Footer. Each component has its file with a .jsx extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/pages&lt;/code&gt;: This directory contains the components for the different pages of the app, such as Home, About, and NotFound. Each page has its file with a .jsx extension.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;src/styles&lt;/code&gt;: This directory contains the custom CSS styles for the app. We use Bootstrap as a base framework and override some styles in our files.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Crafting a Multi-Stage Dockerfile&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The Dockerfile in the &lt;code&gt;frontend&lt;/code&gt; directory employs a multi-stage build to create an optimized Docker image:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stage 1: Building the React Application&lt;/strong&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utilizes &lt;code&gt;node:16.3.0-alpine&lt;/code&gt; for a lightweight build environment. Installs dependencies and builds the application using &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Utilizes &lt;code&gt;node:16.3.0-alpine&lt;/code&gt; for a lightweight build environment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Installs dependencies and builds the application using &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Stage 2: Setting Up the Nginx Server&lt;/strong&gt; &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adopts &lt;code&gt;nginx:alpine&lt;/code&gt; to serve the built React application. Copies the build artifacts and custom Nginx configuration for serving the application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adopts &lt;code&gt;nginx:alpine&lt;/code&gt; to serve the built React application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copies the build artifacts and custom Nginx configuration for serving the application.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Parameterizing Nginx Configuration&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;The custom Nginx configuration (&lt;code&gt;custom-nginx.template&lt;/code&gt;) is designed to proxy API requests to a backend service and serve the React application for other routes. A shell script (&lt;a href="https://github.com/victorgrubio/blog-projects/tree/main/react-nginx-dockerization"&gt;&lt;code&gt;generate-config.sh&lt;/code&gt;&lt;/a&gt;) dynamically generates the final Nginx configuration by substituting environment variables, providing flexibility to define the backend host at runtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Orchestrating Containers with Docker Compose&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Docker Compose is a tool that lets you define and run multiple containers using a YAML file. It simplifies the process of building, running, and connecting containers.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;docker-compose.yaml&lt;/code&gt; file orchestrates the frontend and backend services, ensuring they can communicate and are deployed cohesively:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Local Development &amp;amp; Testing&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;To run the Dockerized React app locally, use &lt;code&gt;docker-compose up&lt;/code&gt; to build and start the containers. Ensure the application communicates with the backend API effectively, and debug using Docker logs and browser developer tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;CI/CD Considerations for Dockerized React Apps&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Integrating CI/CD pipelines, like GitHub Actions, can automate the build, test, and deployment of the Dockerized React app. Define workflows in &lt;code&gt;.github/workflows&lt;/code&gt; to trigger code pushes or pull requests, ensuring continuous delivery and integration.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Build Workflow&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;This workflow triggers every push or pull request to the main branch. It builds and tests both frontend and backend images using Docker commands. It also pushes the images to a Docker registry (such as Docker Hub or GitHub Packages) using secrets to store credentials. We have commented it out on our repo to avoid additional build runs. The code we've used is the following:&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Best Practices &amp;amp; Tips&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Optimize Dockerfile: Leverage Docker layer caching by ordering instructions to install dependencies before copying all source files.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage Images: Regularly prune unused Docker images and containers to manage disk usage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Security: Ensure only necessary ports are exposed and use trusted base images.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;I hope you enjoyed this guide on how to dockerize a React app and make it deployable. You learned how to use Docker, Nginx, and Docker Compose to set up a uniform environment for your app in different phases of development, testing, and production. This will help you streamline your DevOps process and create better software.&lt;/p&gt;

&lt;p&gt;If you liked this article, you can check my other blog posts and my mentorships plans at my &lt;a href="https://mentorcruise.com/mentor/victorgarcia/"&gt;MentorCruise Profile&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks for reading!&lt;/p&gt;

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

&lt;p&gt;Source code: &lt;a href="https://github.com/victorgrubio/blog-projects/tree/main/react-nginx-dockerization"&gt;GitHub repository&lt;/a&gt;&lt;/p&gt;

</description>
      <category>docker</category>
      <category>react</category>
      <category>devops</category>
      <category>nginx</category>
    </item>
    <item>
      <title>Jmeter API Tests from Postman Collection using Loadium</title>
      <dc:creator>Victor Garcia Dev</dc:creator>
      <pubDate>Wed, 06 Oct 2021 15:32:04 +0000</pubDate>
      <link>https://dev.to/victorgarciadev/jmeter-api-tests-from-postman-collection-using-loadium-4e9o</link>
      <guid>https://dev.to/victorgarciadev/jmeter-api-tests-from-postman-collection-using-loadium-4e9o</guid>
      <description>&lt;p&gt;In the &lt;a href="https://www.victorgarciar.com/how-to-create-a-postman-collection-from-openapi-docs" rel="noopener noreferrer"&gt;previous article of this series&lt;/a&gt;, we learned how to create a Postman collection from our OpenAPI documentation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.victorgarciar.com/series/api-design" rel="noopener noreferrer"&gt;Check out the complete series&lt;/a&gt; if you missed it!&lt;/p&gt;

&lt;p&gt;Today we will see in this brief tutorial how to create a Jmeter test suite from our collection using Loadium&lt;/p&gt;

&lt;h1&gt;
  
  
  Import the collection to Loadium
&lt;/h1&gt;

&lt;p&gt;Our test suite will be generated from the Postman collection in the previous chapter. We have all the CRUD functionality of our Idea API if you remember.&lt;/p&gt;

&lt;p&gt;Let's export our collection into JSON.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Right click&lt;/code&gt; on the collection&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Export&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select &lt;code&gt;Collection v2.1 (recommended)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Click again on &lt;code&gt;Export&lt;/code&gt;
&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511478000%2FvUkoZOlWY.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511478000%2FvUkoZOlWY.png" alt="ExportPostmanCollection.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, we have to open a browser and go &lt;a href="https://loadium.com/postman-to-jmeter-converter" rel="noopener noreferrer"&gt;here&lt;/a&gt;. You could also go to the &lt;a href="https://loadium.com" rel="noopener noreferrer"&gt;main Loadium site&lt;/a&gt;. There, select the &lt;code&gt;Features&lt;/code&gt; tab, and click on the &lt;code&gt;Convert Postman to Jmeter&lt;/code&gt;section.&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511518193%2FhODVPAHnlr.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511518193%2FhODVPAHnlr.png" alt="ConvertPostmanToJMX.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It will require you to log in. You could use Google, Github, or Linkedin for doing so, so no worries! After the login process, the home section will appear. Select &lt;code&gt;Convert to .JMX&lt;/code&gt; option, the last one on the left.&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511759431%2Fuyk4NoLON.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511759431%2Fuyk4NoLON.png" alt="OptionsLoadium.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When the form pop-up appears, select the default option &lt;code&gt;POSTMAN&lt;/code&gt;. Then drag your exported collection file to the drop zone. Now your file will be successfully generated. Click in &lt;code&gt;Download JMX&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511586935%2FknPJEnAjS.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511586935%2FknPJEnAjS.png" alt="Step1Loadium.png"&gt;&lt;/a&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511606780%2Fkf_nidirS.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511606780%2Fkf_nidirS.png" alt="Step2Loadium.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Install Jmeter
&lt;/h1&gt;

&lt;p&gt;To install Jmeter, you should follow these steps provided by &lt;a href="https://www.blazemeter.com/blog/how-get-started-jmeter-installation-test-plans" rel="noopener noreferrer"&gt;this Blazemeter article&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://jmeter.apache.org/download_jmeter.cgi" rel="noopener noreferrer"&gt;Download Releases&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Install the most recent 64-bit Java Runtime Environment (JRE) or Java Development Kit (JDK). Because JMeter is a pure Java program, this is critical.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Go to the Apache JMeter website and look for the Binary to save to your PC.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Move this file to your desired location after downloading it. Unpack it, then go to the folder, then the bin directory.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Take a peek around. A set of scripts should appear that can run JMeter in various modes.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For me, I have to run on my Ubuntu terminal&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./jmeter

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

&lt;/div&gt;



&lt;p&gt;and the GUI will appear before my 👀👀&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don't be afraid of the installation process. Is quite easy although it is not very frequent&lt;/p&gt;
&lt;/blockquote&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511637929%2Fk7o2F9G9G.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511637929%2Fk7o2F9G9G.png" alt="GUIJmeter.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Load our JMX and Refactor
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Now we are only a few steps from the glory! 🥳🥳&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's add our JMX file by selecting &lt;code&gt;File&lt;/code&gt; -&amp;gt; &lt;code&gt;Open&lt;/code&gt; and navigate to the location of your downloaded JMX file.&lt;/p&gt;

&lt;p&gt;Now you should see the testing suite loaded in JMeter&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511669357%2FmRrTLCUvM.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511669357%2FmRrTLCUvM.png" alt="LoadedJmeter.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have to make some refactoring to make it work. If you click on one of the requests, you would see something like this:&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511682096%2FZiU7z8jU9.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633511682096%2FZiU7z8jU9.png" alt="requestBeforeRefactor.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We have to make the following changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Split the baseUrl into Protocol - Host - Port&lt;/li&gt;
&lt;li&gt;Refactor the :ideaId parameter into JMX Syntax&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Defining default HTTP request Options
&lt;/h3&gt;

&lt;p&gt;First, we will add some basic variables for configuration. To include a config element, let's right click on the engine wheel and select &lt;code&gt;Add&lt;/code&gt; -&amp;gt; &lt;code&gt;Config Element&lt;/code&gt; -&amp;gt; &lt;code&gt;User Defined Variables&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;We will include two elements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;defaultPath: the prefix path for requests -&amp;gt; &lt;code&gt;/victorgarciar/idea-api/1.0.0&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;server: the domain of our mock server -&amp;gt; &lt;code&gt;virtserver.swaggerhub.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We want to configure the HTTP server once and inherit it on each request. To do so, we have to create an &lt;em&gt;HTTP Request Defaults&lt;/em&gt; element by right-clicking on the engine wheel and selecting &lt;code&gt;Add&lt;/code&gt; -&amp;gt; &lt;code&gt;Config Element&lt;/code&gt; -&amp;gt; &lt;code&gt;HTTP Defaults&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We have to add the server variable. Left the port empty as we are using the 89. It results as follows:&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533703437%2FaAZj70Gu8.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533703437%2FaAZj70Gu8.png" alt="RequestDefaults.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Refactoring Postman syntax to JMX
&lt;/h3&gt;

&lt;p&gt;We have to refactor the &lt;em&gt;ideaId&lt;/em&gt; parameter so that it fits the Jmeter syntax. You can click on &lt;code&gt;Search&lt;/code&gt; -&amp;gt; &lt;code&gt;Search&lt;/code&gt; or the shortcut &lt;code&gt;Ctrl+F&lt;/code&gt;. The search panel will appear.&lt;/p&gt;

&lt;p&gt;Now all we have to do is to change all the &lt;code&gt;:ideaId&lt;/code&gt; to &lt;code&gt;${ideaId}&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Let's include an example ideaId value to our user variables. We could add it dynamically using JSON assertions, but it is out of the scope of the tutorial. If you want more info about it, &lt;a href="https://www.blazemeter.com/blog/api-testing-with-jmeter-and-the-json-extractor" rel="noopener noreferrer"&gt;check this article.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The resultant User variables would be:&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533181364%2F0GmNO9xxa.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533181364%2F0GmNO9xxa.png" alt="UserVariables.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Finally, we have to add the defaultPath variable to each of the requests (I know, this is a heavy con 🥲🥲). If you find out any alternative, please let me know in the comments!&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533157225%2FiJOSDCTtC.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533157225%2FiJOSDCTtC.png" alt="DefaultPathImage.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Add some assertions
&lt;/h3&gt;

&lt;p&gt;We have our requests but, HOW THE HECK WE KNOW THEY ARE WORKING AS EXPECTED !?!?!?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use assertions&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's add some assertions to the requests.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Right Click on any of the requests and select &lt;code&gt;Add&lt;/code&gt; -&amp;gt; &lt;code&gt;Assertions&lt;/code&gt; -&amp;gt; &lt;code&gt;Response Assertion&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Select the Response Code and add the value &lt;code&gt;200&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Change the &lt;code&gt;Pattern Matching Rules&lt;/code&gt; to &lt;code&gt;Equals&lt;/code&gt;
&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533534345%2Fd5IpYV1t-.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533534345%2Fd5IpYV1t-.png" alt="Screenshot from 2021-10-06 17-18-39.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can copy and paste the assertion to all the requests by doing &lt;code&gt;Ctrl+C&lt;/code&gt; to the element, selecting the target request, and &lt;code&gt;Ctrl+V&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Finally, we have to add a listener to the end of the suite to have a summary of the results of our testing process.&lt;/p&gt;

&lt;p&gt;Click on the engine and select &lt;code&gt;Add&lt;/code&gt; -&amp;gt; &lt;code&gt;Listener&lt;/code&gt; and add both &lt;code&gt;View Results Tree&lt;/code&gt; and &lt;code&gt;Assertion results&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These two are the ones I use the most for testing myself. One will show you the data of the requests/response, very useful for debugging. The other one will show you the results of your assertions. The results tree would show anything different from a 2XX code as an error, but you may want to test error cases. That's when the &lt;code&gt;Assertion results&lt;/code&gt; come in handy.&lt;/p&gt;

&lt;h1&gt;
  
  
  Lauch your test suite
&lt;/h1&gt;

&lt;p&gt;Now we are ready to test! 🥳🥳&lt;/p&gt;

&lt;p&gt;We didn't make a single line of code, remember. So, have to use the mock server we created in a previous article. For using it we have to set up the HTTP Request options to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Protocol: HTTPS&lt;/li&gt;
&lt;li&gt;Server: domain of your mock server. In my case ``&lt;/li&gt;
&lt;li&gt;Port: Empty or 80. It's the same.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let's launch it!! Go and click on the RUN button in the toolbar.&lt;/p&gt;

&lt;p&gt;You should check your assertions and see EVERYTHING IS GREEN 💚 (Mock's magic 🪄🪄)&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533107934%2FTjbcVuOJU.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533107934%2FTjbcVuOJU.png" alt="Screenshot from 2021-10-06 17-11-13.png"&gt;&lt;/a&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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533110876%2FBGCmcnXIB.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%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1633533110876%2FBGCmcnXIB.png" alt="Screenshot from 2021-10-06 17-11-23.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And that's it! You have created a test suite for your API design!&lt;/p&gt;

&lt;p&gt;I know there are some alternatives like Newman which I have to test yet. But I find Jmeter to be very complete, as we have additional options, out of the scope of the article like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Checking DB rows&lt;/li&gt;
&lt;li&gt;Checking Redis/Cache status with custom Beanshell scripts&lt;/li&gt;
&lt;li&gt;JSON Assertions&lt;/li&gt;
&lt;li&gt;Way other things I don't know 😁😁&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;In this article, I hope you have learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Convert your Postman collection to a JMeter file using Loadium&lt;/li&gt;
&lt;li&gt;Install Jmeter &lt;/li&gt;
&lt;li&gt;Configure a Jmeter file and add assertions&lt;/li&gt;
&lt;li&gt;Execute a Test Suite in Jmeter&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%2Fmedia.giphy.com%2Fmedia%2F8WJw9kAG3wonu%2Fgiphy.gif%3Fcid%3Decf05e476rq397rl82lfotvyar9xwkkrl5wgzrk8p9mr1akx%26rid%3Dgiphy.gif" 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%2Fmedia.giphy.com%2Fmedia%2F8WJw9kAG3wonu%2Fgiphy.gif%3Fcid%3Decf05e476rq397rl82lfotvyar9xwkkrl5wgzrk8p9mr1akx%26rid%3Dgiphy.gif" alt="patrick-fun-gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am HONOURED if you have reached this point. Thanks a lot for reading 💙&lt;/p&gt;

&lt;p&gt;Hopefully, I was able to explain how to create a Jmeter test file from a Postman, configure, and run it!&lt;/p&gt;

&lt;p&gt;Reach out on &lt;a href="https://twitter.com/VictorGarciaDev" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; to find more valuable content or just chatting!&lt;/p&gt;

&lt;p&gt;🐦 &lt;a href="https://twitter.com/VictorGarciaDev" rel="noopener noreferrer"&gt;@victorgarciadev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;😼 &lt;a href="https://github.com/victorgrubio" rel="noopener noreferrer"&gt;github.com/victorgrubio&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.victorgarciar.com/series/api-design" rel="noopener noreferrer"&gt;Complete Series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.blazemeter.com/blog/how-get-started-jmeter-installation-test-plans" rel="noopener noreferrer"&gt;Blazemeter article&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://loadium.com" rel="noopener noreferrer"&gt;Loadium site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://jmeter.apache.org/usermanual/index.html" rel="noopener noreferrer"&gt;Jmeter docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks and Keep It Up! 🦾🦾&lt;/p&gt;

</description>
      <category>api</category>
      <category>testing</category>
      <category>postman</category>
    </item>
    <item>
      <title>How to create a Postman Collection from OpenAPI Docs</title>
      <dc:creator>Victor Garcia Dev</dc:creator>
      <pubDate>Tue, 28 Sep 2021 09:39:10 +0000</pubDate>
      <link>https://dev.to/victorgarciadev/how-to-create-a-postman-collection-from-openapi-docs-4ckk</link>
      <guid>https://dev.to/victorgarciadev/how-to-create-a-postman-collection-from-openapi-docs-4ckk</guid>
      <description>&lt;p&gt;In the &lt;a href="https://www.victorgarciar.com/api-documentation-with-openapi"&gt;previous article of this series&lt;/a&gt;, we learned how to create the documentation for your API using OpenAPI.&lt;/p&gt;

&lt;p&gt;If you didn't check it out, what are you waiting for !?!? 😁😁&lt;/p&gt;

&lt;p&gt;Today we will see in this brief tutorial how to create a &lt;a href="https://www.postman.com"&gt;Postman&lt;/a&gt; collection from this documentation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Download API docs
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;We have different ways to download the YAML file containing the documentation. It depends on how we stored it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Swagger Editor
&lt;/h3&gt;

&lt;p&gt;Swagger Editor stores the status of your last edition. Yet, if you have to delete information from your browser, all your progress may be lost! 🆘🆘&lt;/p&gt;

&lt;p&gt;Swagger Editor is an excellent tool for fast edition and linting your files. However, if the documentation is large and will take you days, then use editors like Notepad++, Gedit, or VSCode to write it.&lt;/p&gt;

&lt;p&gt;To download the API documentation file from Swagger Editor, we have to click on: &lt;code&gt;Edit&lt;/code&gt;-&amp;gt; &lt;code&gt;Save as YAML&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XPsiV37B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/UtPeRW1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XPsiV37B--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.imgur.com/UtPeRW1.png" alt="Save-as-yaml-swagger-editor.png" width="667" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The browser will download an &lt;code&gt;openapi.yaml&lt;/code&gt; file.&lt;/p&gt;

&lt;h3&gt;
  
  
  SwaggerHub
&lt;/h3&gt;

&lt;p&gt;Swagger Hub stores the information on their servers. There is nothing to worry about here 🤗 To download it, we have to click on our API project.&lt;/p&gt;

&lt;p&gt;Once we are editing our project, we have to click on &lt;code&gt;Export&lt;/code&gt; -&amp;gt; &lt;code&gt;Download API&lt;/code&gt; -&amp;gt; &lt;code&gt;YAML Resolved&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1ZHgyjhc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820916125/6O3lg2uvh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1ZHgyjhc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820916125/6O3lg2uvh.png" alt="Swaggerhub-export-process.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I think this is the best format to do so. JSON will be valid as well, although I find YAML easier to edit.&lt;/p&gt;




&lt;h2&gt;
  
  
  Import it to Postman
&lt;/h2&gt;

&lt;p&gt;Now, go on and open Postman. If you don't have it, you can download it from &lt;a href="https://www.postman.com/downloads/"&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We are going to select the &lt;code&gt;APIs&lt;/code&gt; tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SiuPDfnG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820815169/esC3Wjjrw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SiuPDfnG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820815169/esC3Wjjrw.png" alt="Postman-api-section.png" width="639" height="531"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then let's click on &lt;code&gt;Import&lt;/code&gt; and select the OpenAPI docs file. Confirm that you want the Collection to act as &lt;code&gt;Documentation&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qfmOlDEK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632819244523/29-Ygx4ln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qfmOlDEK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632819244523/29-Ygx4ln.png" alt="Collection-generation-step.png" width="555" height="657"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you check the APIs section, the definition of your OpenAPI Documentation should appear.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gDdEVJqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632819312132/Iq4FyFRGE.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gDdEVJqT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632819312132/Iq4FyFRGE.png" alt="API-definition-postman.png" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Moreover, the generated collection will appear in the &lt;code&gt;Collections&lt;/code&gt; tab. You should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--uMBuVFGv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632819332607/F9MHoaXf-.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uMBuVFGv--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632819332607/F9MHoaXf-.png" alt="Postman-collection.png" width="766" height="404"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a Mock Server in Swaggerhub
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Do you have a server to make requests to? NO? LET'S MOCK IT THEN!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Before testing our API, we have to create a &lt;em&gt;Mock Server&lt;/em&gt; to make requests to! To do so, we are going to take advantage of the &lt;em&gt;Integrations&lt;/em&gt; available at SwaggerHub.&lt;/p&gt;

&lt;p&gt;Click on your API name inside the editor and delete &lt;code&gt;Integrations&lt;/code&gt; tab.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tAnY8fYL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820629074/PVe6HwLJV.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tAnY8fYL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820629074/PVe6HwLJV.png" alt="Integrations.png" width="730" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, add new integration and select &lt;code&gt;API Auto Mocking&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZIVAl4T7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820597708/s6Sp1neBX.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZIVAl4T7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820597708/s6Sp1neBX.png" alt="AutoMocking-selection.png" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Set your API name to whatever you want. In this case, I defined &lt;code&gt;Idea API&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QMqkdBAC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820648785/ddgWp2h-N.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QMqkdBAC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820648785/ddgWp2h-N.png" alt="Form-with-api-name.png" width="800" height="669"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now the integration is completed. We have our mock server up and running! The address has the following format:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://virtserver.swaggerhub.com/&amp;lt;owner&amp;gt;/&amp;lt;api-name&amp;gt;/&amp;lt;version&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In my case, this results in &lt;code&gt;https://virtserver.swaggerhub.com/victorgarciar/idea-api/1.0.0&lt;/code&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Test!
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;You can't say "It works!" if you haven't tested it yourself&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let's go back to our Postman Collection and set the "baseUrl" variable to the URL of our mock server.&lt;/p&gt;

&lt;p&gt;Click on the Collection's name and select the &lt;code&gt;Variables&lt;/code&gt; tab. You will have a variable there named "baseUrl" as mentioned. Delete the current value and paste your mock server URL!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hJhSORUQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820689933/ZNKmeNrYp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hJhSORUQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820689933/ZNKmeNrYp.png" alt="Postman-variables.png" width="800" height="175"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we have everything set up! Go to one of the requests and send it. You should see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0HBj1n2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820727833/Hx28X-NLL.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0HBj1n2K--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632820727833/Hx28X-NLL.png" alt="Postman-request.png" width="800" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Of course, results will make no sense since we are using a mock server. Don't forget!&lt;/p&gt;




&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;In this article, I hope you have learned:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Downloading your API docs&lt;/li&gt;
&lt;li&gt;Importing it to Postman&lt;/li&gt;
&lt;li&gt;Creating a mock server in SwaggerHub&lt;/li&gt;
&lt;li&gt;Test your API with a mock server&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nJHX_S_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media.giphy.com/media/8WJw9kAG3wonu/giphy.gif%3Fcid%3Decf05e476rq397rl82lfotvyar9xwkkrl5wgzrk8p9mr1akx%26rid%3Dgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nJHX_S_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media.giphy.com/media/8WJw9kAG3wonu/giphy.gif%3Fcid%3Decf05e476rq397rl82lfotvyar9xwkkrl5wgzrk8p9mr1akx%26rid%3Dgiphy.gif" alt="patrick-fun-gif" width="500" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am HONOURED if you have reached this point. Thanks a lot for reading 💙&lt;/p&gt;

&lt;p&gt;Hopefully, I was able to explain how to import OpenAPI docs to Postman and create a Mock Server in SwaggerHub to test it!&lt;/p&gt;

&lt;p&gt;Reach out on &lt;a href="https://twitter.com/VictorGarciaDev"&gt;Twitter&lt;/a&gt; to find more valuable content or just chatting!&lt;/p&gt;

&lt;p&gt;🐦 &lt;a class="mentioned-user" href="https://dev.to/victorgarciadev"&gt;@victorgarciadev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;😼 &lt;a href="https://github.com/victorgrubio"&gt;https://github.com/victorgrubio&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.victorgarciar.com/api-documentation-with-openapi"&gt;Previous Article of the Series&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://swagger.io/docs/specification/about/"&gt;OpenAPI Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://support.smartbear.com/swaggerhub/docs/integrations/api-auto-mocking.html"&gt;SwaggerHub Integrations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks and Keep It Up! 🦾🦾&lt;/p&gt;

</description>
      <category>postman</category>
      <category>api</category>
      <category>openapi</category>
    </item>
    <item>
      <title>API Documentation with OpenAPI</title>
      <dc:creator>Victor Garcia Dev</dc:creator>
      <pubDate>Mon, 27 Sep 2021 17:49:52 +0000</pubDate>
      <link>https://dev.to/victorgarciadev/api-documentation-with-openapi-pga</link>
      <guid>https://dev.to/victorgarciadev/api-documentation-with-openapi-pga</guid>
      <description>&lt;p&gt;Your backend needs an API to expose all its value to the world. You already know that. And it should be well commented to avoid any user misusing or hate to use it.&lt;/p&gt;

&lt;p&gt;An API can be considered as the contract between the &lt;strong&gt;information provider&lt;/strong&gt; (a lovely &lt;em&gt;backend developer&lt;/em&gt;, like me 😇) and the &lt;strong&gt;consumer&lt;/strong&gt; (an &lt;em&gt;awful frontend&lt;/em&gt; developer, like me 😈). There, the content required for the producer ( &lt;strong&gt;request&lt;/strong&gt; ) to provide the information that the consumer needs ( &lt;strong&gt;response&lt;/strong&gt; ) is defined.&lt;/p&gt;

&lt;p&gt;There we hide all of our terrible backend logic from our users and give them a nice, simple way to use our services. And, if it is in exchange for money, better 💸💸💸&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--e_uuNvXe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.pinimg.com/originals/5b/d6/8c/5bd68c6d04eb8a54e0bab9380b46db3b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--e_uuNvXe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.pinimg.com/originals/5b/d6/8c/5bd68c6d04eb8a54e0bab9380b46db3b.png" alt="backend-frontend-meme.png" width="640" height="605"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  OpenAPI
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Okay Victor, I know a little bit about APIs, maybe I even know how to create one ... BUT HOW THE F DO I DOCUMENT IT?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Nice question. Tons of people did the same one. Some of them united and created the &lt;a href="https://swagger.io/docs/specification/about/"&gt;OpenAPI Specification (OAS)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The OpenAPI Specification defines a standard, language-agnostic interface to RESTful which permits both people and computers to find and get the value from the services without getting to source code or documentation. If defined properly, users can understand and interact with the remote service with a low effort from their site. I mean, at least they need access to the Internet 😅😅&lt;/p&gt;

&lt;p&gt;An OpenAPI file allows you to describe your entire API, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Available endpoints (/ideas) and methods on each endpoint (GET /ideas, POST /ideas)&lt;/li&gt;
&lt;li&gt;Operation parameters Input and output for each method&lt;/li&gt;
&lt;li&gt;Authentication methods&lt;/li&gt;
&lt;li&gt;Contact information, license, terms of use, and other information.&lt;/li&gt;
&lt;/ul&gt;




&lt;h1&gt;
  
  
  Documentation-First vs Code-First Workflow
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;To &lt;em&gt;code first&lt;/em&gt; or to &lt;em&gt;document first&lt;/em&gt;, that is the question&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I have created quite a few APIs, most of them using API documentation. Some developers like to create the OpenAPI file &lt;strong&gt;from the development&lt;/strong&gt;. Most programming languages and frameworks have a plugin to generate OpenAPI documentation from your code.&lt;/p&gt;

&lt;p&gt;A list for some of the most used:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/flasgger/flasgger"&gt;Flask&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://django-rest-swagger.readthedocs.io/en/latest/"&gt;Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://springdoc.org/#Introduction"&gt;Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.npmjs.com/package/swagger-ui-express"&gt;NodeJS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is another way to view it. Automatically creating your code &lt;strong&gt;from the documentation&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;As OpenAPI doesn't care about your programming language, it is able to generate code from the YAML/JSON file to the framework you specify. Then, you just need to create the server logic and your API is ready to go!&lt;/p&gt;

&lt;p&gt;Some useful tools that allow you to generate code from the documentation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/OpenAPITools/openapi-generator"&gt;OpenAPI Generator&lt;/a&gt; - Open Source Tool to create client/server versions of our API&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://editor.swagger.io/"&gt;Swagger Online Editor&lt;/a&gt; - Edit &amp;amp; Lint your OpenAPI files&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://swagger.io/tools/swaggerhub/"&gt;SwaggerHub&lt;/a&gt; - Design &amp;amp; Publish your documentation&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://swagger.io/tools/swagger-codegen/"&gt;Swagger Codegen&lt;/a&gt; - A Swagger tool to generate client libraries for your API in over 40 languages and generate a server stub for your API.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x_YV3jq1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://static1.smartbear.co/swagger/media/images/tools/opensource/swagger_codegen.png%3Fext%3D.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x_YV3jq1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://static1.smartbear.co/swagger/media/images/tools/opensource/swagger_codegen.png%3Fext%3D.png" alt="AvailableOpenAPI.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Create an OpenAPI documentation file
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Let's make an example to learn&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Idea API
&lt;/h3&gt;

&lt;p&gt;To illustrate most of the concepts without creating a difficult logic, let's create an Idea API.&lt;/p&gt;

&lt;p&gt;This will be a simple &lt;strong&gt;Create Read Update Delete (CRUD)&lt;/strong&gt; API, with just the Idea as a model (no users or anything like that)&lt;/p&gt;

&lt;h2&gt;
  
  
  Definition &amp;amp; Concepts
&lt;/h2&gt;

&lt;p&gt;First, go to [Swagger Online Editor]. It will show the classic PetStore Example using Swagger 2.0. We will like to convert this example to OpenAPI v3.&lt;/p&gt;

&lt;p&gt;To do so, click on &lt;strong&gt;Edit -&amp;gt; Convert to OpenAPI 3&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now let's delete most of it, leaving only the top part, without any paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openapi: 3.0.1
info:
  title: Swagger Petstore
  description: 'This is a sample server Petstore server. You can find out more about Swagger
    at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For
    this sample, you can use the api key `special-key` to test the authorization filters.'
  termsOfService: http://swagger.io/terms/
  contact:
    email: apiteam@swagger.io
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  version: 1.0.0
externalDocs:
  description: Find out more about Swagger
  url: http://swagger.io
servers:
- url: https://petstore.swagger.io/v2
- url: http://petstore.swagger.io/v2
tags:
- name: pet
  description: Everything about your Pets
  externalDocs:
    description: Find out more
    url: http://swagger.io
- name: store
  description: Access to Petstore orders
- name: user
  description: Operations about user
  externalDocs:
    description: Find out more about our store
    url: http://swagger.io
paths:
components:
security:

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

&lt;/div&gt;



&lt;p&gt;Let me describe all the keys used in the previous piece of documentation&lt;/p&gt;

&lt;p&gt;| Property | Description | Type | Value | More Info |&lt;br&gt;
| openapi | Version of OpenAPI you are using | Version String | 3.0.1 | &lt;a href="https://swagger.io/docs/specification/basic-structure/"&gt;https://swagger.io/docs/specification/basic-structure/&lt;/a&gt; |&lt;br&gt;
| info | Description of your API | Object | termsOfService: &lt;a href="http://swagger.io/terms/"&gt;http://swagger.io/terms/&lt;/a&gt; contact: email: &lt;a href="mailto:apiteam@swagger.io"&gt;apiteam@swagger.io&lt;/a&gt; license: name: Apache 2.0 url: &lt;a href="http://www.apache.org/licenses/LICENSE-2.0.html"&gt;http://www.apache.org/licenses/LICENSE-2.0.html&lt;/a&gt; version: 1.0.0 | &lt;a href="https://swagger.io/docs/specification/basic-structure/"&gt;https://swagger.io/docs/specification/basic-structure/&lt;/a&gt; |&lt;br&gt;
| servers | List of servers to make requests to | List of urls | - url: &lt;a href="https://petstore.swagger.io/v2"&gt;https://petstore.swagger.io/v2&lt;/a&gt; - url: &lt;a href="http://petstore.swagger.io/v2"&gt;http://petstore.swagger.io/v2&lt;/a&gt; | &lt;a href="https://swagger.io/docs/specification/api-host-and-base-path/"&gt;https://swagger.io/docs/specification/api-host-and-base-path/&lt;/a&gt; |&lt;br&gt;
| tags | List of groups where endpoints can be joined | List | - name: pet description: Everything about your Pets externalDocs: description: Find out more url: &lt;a href="http://swagger.io"&gt;http://swagger.io&lt;/a&gt; | &lt;a href="https://swagger.io/docs/specification/basic-structure/"&gt;https://swagger.io/docs/specification/basic-structure/&lt;/a&gt; |&lt;br&gt;
| paths | List of endpoints available for the API, along with the methods | Object | /ideas: - get: description: List all ideas | &lt;a href="https://swagger.io/docs/specification/paths-and-operations/"&gt;https://swagger.io/docs/specification/paths-and-operations/&lt;/a&gt; |&lt;br&gt;
| parameters | List of parameters using in the API | Object | parameters: Id: description: Id of the Idea type: integer | &lt;a href="https://swagger.io/docs/specification/describing-parameters/"&gt;https://swagger.io/docs/specification/describing-parameters/&lt;/a&gt; |&lt;br&gt;
| components | List of Schemas available in the API | Object | components Idea: description: Idea model required: - id properties: id: description: id of object type: integer | &lt;a href="https://swagger.io/docs/specification/components/"&gt;https://swagger.io/docs/specification/components/&lt;/a&gt; |&lt;br&gt;
| security | Security / Authentication of the API | Object | security: - ApiKeyAuth: [] - OAuth2: - read - write | &lt;a href="https://swagger.io/docs/specification/authentication/"&gt;https://swagger.io/docs/specification/authentication/&lt;/a&gt; |&lt;br&gt;
| externalDocs | Url to external documentation of the API | Object (description/url) | externalDocs: name: Example externals url: &lt;a href="http://swagger.io"&gt;http://swagger.io&lt;/a&gt; | &lt;a href="https://swagger.io/docs/specification/basic-structure/"&gt;https://swagger.io/docs/specification/basic-structure/&lt;/a&gt; |&lt;/p&gt;

&lt;p&gt;As mentioned before, you have a detailed explanation in the &lt;a href="https://swagger.io/docs/specification/about/"&gt;OpenAPI Documentation&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will see alerts in the editor. No worries, we have to define our methods yet.&lt;/p&gt;

&lt;p&gt;These methods are the services we allow the users to interact with. As some of you may know the most common HTTP methods are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;GET&lt;/code&gt;&lt;/strong&gt; -&amp;gt; Retrieves information&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;POST&lt;/code&gt;&lt;/strong&gt; -&amp;gt; Send loads of data to a server to create or update a resource&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PUT&lt;/code&gt;&lt;/strong&gt; -&amp;gt; Complete update of an object&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;PATCH&lt;/code&gt;&lt;/strong&gt; -&amp;gt; Partial update of an object&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;DELETE&lt;/code&gt;&lt;/strong&gt; -&amp;gt; Remove object&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other additional methods, less common but also important:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;HEAD&lt;/code&gt;&lt;/strong&gt; -&amp;gt; Equal to &lt;code&gt;GET&lt;/code&gt;, without receiving response items (Check that GET works)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;OPTIONS&lt;/code&gt;&lt;/strong&gt; -&amp;gt; Returns data describing what other methods and operations the server supports at the given URL&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A detailed article about HTTP methods is available &lt;a href="https://assertible.com/blog/7-http-methods-every-web-developer-should-know-and-how-to-test-them"&gt;here&lt;/a&gt;, as it is out of the scope of this one.&lt;/p&gt;
&lt;h3&gt;
  
  
  Endpoint Creation &amp;amp; Parameters
&lt;/h3&gt;

&lt;p&gt;As mentioned before, we are going to use GET, POST, PUT and DELETE methods for our API.&lt;/p&gt;

&lt;p&gt;Let's create the List and Create endpoints:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;openapi: 3.0.1
info:
  title: Idea API
  description: 'This is a sample server for the Idea API from the blog post "API Documentation with OpenAPI" by @victorgarciadev'
  termsOfService: http://swagger.io/terms/
  contact:
    email: victorgrubiodl@gmail.com 
  license:
    name: MIT
    url: https://opensource.org/licenses/MIT
  version: 1.0.0
externalDocs:
  description: Blog with amazing articles
  url: https://www.victorgarciar.com
servers:
- url: https://petstore.swagger.io/v2
tags:
- name: ideas
  description: Everything about your Ideas
paths:
  /ideas:
    get:
      summary: List all ideas
      description: Retrieves a list of all the ideas available
      tags:
       - ideas
      responses:
       "200":
          description: List of ideas
          content:
            application/json:
              schema:
                type: array
                items:
                 $ref: '#/components/schemas/Idea'
       "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                 message: 
                   type: string
                   description: Error message
                   example: 'This is an error message for Internal Server Error'
    post:
      summary: Create idea
      description: Creates a new idea from its basic data
      tags:
       - ideas
      requestBody:
        description: Data from idea that will be created
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Idea'
            example:
              description: Idea to create
      responses:
       "200":
          description: The created idea
          content:
            application/json:
              schema:
               $ref: '#/components/schemas/Idea'
       "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                 message: 
                   type: string
                   description: Error message
                   example: 'This is an error message for Internal Server Error'
components:
  schemas:
    Idea:
      type: object
      description: Idea
      properties:
       id: 
        type: integer
        description: id of item
        minimum: 1
       description:
        type: string
        description: Description of idea

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

&lt;/div&gt;



&lt;p&gt;And that should render to something like this&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fP5KjYs5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632761526640/8lrXcTCmI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fP5KjYs5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632761526640/8lrXcTCmI.png" alt="image.png" width="800" height="694"&gt;&lt;/a&gt;NOTE: You can observe that we have refactored the metadata of our API to be adjusted to this project.&lt;/p&gt;

&lt;p&gt;Now let's create the Read, Update and Delete endpoints. Below the definition of the &lt;em&gt;/ideas&lt;/em&gt; path, add the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/ideas/{ideaId}:
    get:
      summary: List all ideas
      description: Retrieves a list of all the ideas available
      tags:
       - ideas
      parameters:
        - name: ideaId
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
       "200":
          description: Idea requested
          content:
            application/json:
              schema:
                 $ref: '#/components/schemas/Idea'
       "404":
          $ref: '#/components/responses/404NotFound'
       "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                 message: 
                   type: string
                   description: Error message
                   example: 'This is an error message for Internal Server Error'
    put:
      summary: Updates an idea
      description: Performs an update of an specific idea by the data provided
      tags:
       - ideas
      parameters:
        - name: ideaId
          in: path
          required: true
          schema:
            type: integer
            format: int64
      requestBody:
        description: Data to update the idea
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Idea'
            example:
              description: Idea to update
      responses:
       "200":
          description: Updated idea
          content:
            application/json:
              schema:
                 $ref: '#/components/schemas/Idea'
       "404":
          $ref: '#/components/responses/404NotFound'
       "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                 message: 
                   type: string
                   description: Error message
                   example: 'This is an error message for Internal Server Error'
    delete:
      summary: Deletes an idea
      description: Removes an idea if exists
      tags:
       - ideas
      parameters:
        - name: ideaId
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
       "200":
          description: Empty body for ok
          content:
            application/json:
              schema:
                type: object
       "404":
          $ref: '#/components/responses/404NotFound'
       "500":
          description: Internal Server Error
          content:
            application/json:
              schema:
                type: object
                properties:
                 message: 
                   type: string
                   description: Error message
                   example: 'This is an error message for Internal Server Error'

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

&lt;/div&gt;



&lt;p&gt;Here we can see that we have included a parameter. They can be either specified in the same method (&lt;em&gt;Read Method&lt;/em&gt;) or we can create a reference to them in the &lt;strong&gt;Parameters&lt;/strong&gt; section of the documentation (&lt;em&gt;Update Method&lt;/em&gt;)&lt;/p&gt;

&lt;h3&gt;
  
  
  Model Definition &amp;amp; Object Reference
&lt;/h3&gt;

&lt;p&gt;As you may observe, request bodies and responses include a reference to an Idea object. In the schemas' part, we define all the objects we may use for our bodies and responses. This will create a much more organized structure and reduce duplicities.&lt;/p&gt;

&lt;p&gt;A Schema contains the following properties:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Summary -&amp;gt; Brief description of the object&lt;/li&gt;
&lt;li&gt;Description -&amp;gt; Complete information about the model&lt;/li&gt;
&lt;li&gt;Required -&amp;gt; List of required properties for the model&lt;/li&gt;
&lt;li&gt;Properties -&amp;gt; List of attributes of the model&lt;/li&gt;
&lt;li&gt;Example -&amp;gt; Object used to complete the documentation as default. Could be one or more. &lt;a href="https://swagger.io/docs/specification/adding-examples/"&gt;Documentation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A more detailed explanation about attribute types and object creation can be found in the &lt;a href="https://swagger.io/docs/specification/data-models/"&gt;OpenAPI Section&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An example would be the Idea model&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;    Idea:
      type: object
      description: Idea
      properties:
       id: 
        type: integer
        description: id of item
        minimum: 1
       description:
        type: string
        description: Description of idea

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

&lt;/div&gt;



&lt;p&gt;We can reference it in the documentation with the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;              schema:
                 $ref: '#/components/schemas/Idea'

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

&lt;/div&gt;



&lt;p&gt;This applies also to responses and parameters:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   delete:
      summary: Deletes an idea
      description: Removes an idea if exists
      tags:
       - ideas
      parameters:
        - name: ideaId
          in: path
          required: true
          schema:
            type: integer
            format: int64
      responses:
       "200":
          description: Empty body for ok
          content:
            application/json:
              schema:
                type: object
       "404":
          $ref: '#/components/responses/404NotFound'

  responses:
    404NotFound:
      description: Not Found
      content:
        application/json:
          schema:
            type: object
            properties:
             message: 
               type: string
               description: Error message

          example: 'Idea with id requested not found in server'

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

&lt;/div&gt;



&lt;p&gt;More info about referencing &lt;a href="https://swagger.io/docs/specification/using-ref/"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;We are going to add a simple API Key security layer for the sake of completeness. To do so, we are going to define a &lt;code&gt;Security Schemes&lt;/code&gt; property at the root of the document&lt;/p&gt;

&lt;p&gt;The security schema may vary in type depending on your project's conditions. We can define the security in a more granular way by specifying it on each method.&lt;/p&gt;

&lt;p&gt;We have to add the API Key auth to the &lt;code&gt;securitySchemes&lt;/code&gt; property at &lt;em&gt;Components&lt;/em&gt;. Then add the &lt;code&gt;security&lt;/code&gt; property, at the same level of paths, components, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-Key
security:
  - apiKey: []

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

&lt;/div&gt;



&lt;p&gt;More info about Security Schemes in OpenAPI &lt;a href="https://swagger.io/docs/specification/authentication/"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h1&gt;
  
  
  Share it online with SwaggerHub
&lt;/h1&gt;

&lt;blockquote&gt;
&lt;p&gt;Someone may use your API one day. Go on and share it!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we have our API ready, let's share it with everyone. As you may know, if you follow my &lt;em&gt;Daily Dev Tips&lt;/em&gt; from &lt;a href="https://twitter.com/VictorGarciaDev"&gt;Twitter&lt;/a&gt;, I like a lot Swaggerhub to define and expose our API documentation.&lt;/p&gt;

&lt;p&gt;Let's create a new Project there, checking &lt;code&gt;Import and document API&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rOuLmdCE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632763294413/1mrW29z40.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rOuLmdCE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632763294413/1mrW29z40.png" alt="create-swaggerhub.png" width="653" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then, we can download our OpenAPI documentation file from Swagger Editor and add it to the project&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fjR6qlcF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632763319446/hAvHf6fVI.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fjR6qlcF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632763319446/hAvHf6fVI.png" alt="export-api-editor.png" width="667" height="333"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And it's done, we have our API documentation published for everyone to see. &lt;a href="https://app.swaggerhub.com/apis-docs/victorgarciar/idea-api/1.0.0"&gt;Here's mine&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1oDdupx3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632763508289/j-bY50G8E.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1oDdupx3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1632763508289/j-bY50G8E.png" alt="swaggerhub-loaded.png" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h1&gt;
  
  
  Summary
&lt;/h1&gt;

&lt;p&gt;We have (I hope) learned in this article:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's an API&lt;/li&gt;
&lt;li&gt;Why is important to document your APIs with OpenAPI&lt;/li&gt;
&lt;li&gt;How an OpenAPI documentation file looks like&lt;/li&gt;
&lt;li&gt;Implement OpenAPI documentation for a CRUD API&lt;/li&gt;
&lt;li&gt;Share it using Swaggerhub&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--nJHX_S_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media.giphy.com/media/8WJw9kAG3wonu/giphy.gif%3Fcid%3Decf05e476rq397rl82lfotvyar9xwkkrl5wgzrk8p9mr1akx%26rid%3Dgiphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--nJHX_S_5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_800/https://media.giphy.com/media/8WJw9kAG3wonu/giphy.gif%3Fcid%3Decf05e476rq397rl82lfotvyar9xwkkrl5wgzrk8p9mr1akx%26rid%3Dgiphy.gif" alt="patrick-fun-gif" width="500" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am HONOURED if you have reached this point. Thanks a lot for reading 💙&lt;/p&gt;

&lt;p&gt;Hopefully, I was able to explain the importance of API documentation and how to do it using OpenAPI.&lt;/p&gt;

&lt;p&gt;Reach out on &lt;a href="https://twitter.com/VictorGarciaDev"&gt;Twitter&lt;/a&gt; to find more valuable content or just chatting!&lt;/p&gt;

&lt;p&gt;🐦 &lt;a class="mentioned-user" href="https://dev.to/victorgarciadev"&gt;@victorgarciadev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;😼 &lt;a href="https://github.com/victorgrubio"&gt;https://github.com/victorgrubio&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://swagger.io/docs/specification/about/"&gt;OpenAPI Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://assertible.com/blog/7-http-methods-every-web-developer-should-know-and-how-to-test-them"&gt;HTTP Methods&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks and Keep It Up! 🦾🦾&lt;/p&gt;

</description>
      <category>api</category>
      <category>openapi</category>
    </item>
    <item>
      <title>Unleash Your Learning Potential through Writing</title>
      <dc:creator>Victor Garcia Dev</dc:creator>
      <pubDate>Fri, 17 Sep 2021 13:40:01 +0000</pubDate>
      <link>https://dev.to/victorgarciadev/unleash-your-learning-potential-through-writing-2fc2</link>
      <guid>https://dev.to/victorgarciadev/unleash-your-learning-potential-through-writing-2fc2</guid>
      <description>&lt;p&gt;Many of us may have tried to start technical writing and left it after a week. Perhaps you've created a blog but stopped posting after a year. You might have wondered if you would ever be the one offering valuable replies on Stack Overflow.&lt;/p&gt;

&lt;p&gt;If you can relate to these experiences, allow me to share my main motivation for writing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Writing helps me learn better
&lt;/h3&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Traditional Learning Methods
&lt;/h2&gt;

&lt;p&gt;Let's face it, traditional learning methods often fall short. During my college years as a Telecommunications Engineering student, I had to absorb a lot of information in a limited time frame. Picture this: 8 exams in just 4 days. It was intense. Initially, I relied on memorizing exercises from previous years and regurgitating fixed patterns. And it worked for a while.&lt;/p&gt;

&lt;p&gt;What would I do? What they have educated me for: Try to learn how to do some exercises from previous years. Memorize the parts that are always asked the same way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dwzbQWj5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631884055242/v5Tc1M-O6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dwzbQWj5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631884055242/v5Tc1M-O6.jpeg" alt="tony-tran-F8sCVSW4t4E-unsplash (1).jpg" width="640" height="960"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It worked for a while&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, everything changed when I pursued a Machine Learning master's degree. The complex math I encountered demanded a deeper level of understanding. Thanks to exceptional teachers, I shifted my focus to grasping concepts and truly comprehending them. The knowledge gained during that period remains etched in my mind.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here is when everything made sense.
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Overcome the Tutorial Syndrome
&lt;/h2&gt;

&lt;p&gt;We were born in the era of YouTube, where countless videos exist on practically every topic imaginable. Content creators possess an infinite wealth of knowledge at their fingertips. But let's pause and reflect: How much of that content do we retain after three days? I remember very little. Please don't misunderstand meI appreciate YouTube and the incredible free content it offers.&lt;/p&gt;

&lt;p&gt;However, watching videos, reading books, and scrolling through posts are all passive activities. They require less attention compared to activities like coding. On occasion, I've stumbled across intriguing concepts in books that have fascinated me and triggered a surge of dopamine. Yet, more often than not, those highlighted passages quickly fade from memory. In contrast, lines of code and text that I've created through sweat and perseverance tend to leave a lasting impression.&lt;/p&gt;

&lt;h2&gt;
  
  
  Enhancing Understanding of Topics
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Name a topic that writing didnt help you understand better. It's hard, isn't it?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me share an example from my own experience. I was reading "Head First Design Patterns"a highly recommended book. Each chapter delved deep into one or more &lt;a href="https://en.wikipedia.org/wiki/Software_design_pattern"&gt;design patterns&lt;/a&gt;. Although I read it almost every day, after a week, I realized I couldn't recall any of the patterns or how to apply them.&lt;/p&gt;

&lt;p&gt;That's when I decided to tackle a different approach. I opted to code the design patterns in a different programming language. Since the book's examples were in Java, I chose Python as the obvious choice for me.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It took me three days to make the Abstract Factory pattern work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But let me assure you, after that intensive exercise, I truly understood how to implement the abstract factory pattern. As a fun side note, I also became well-versed in modeling a pizza franchise business! 😆&lt;/p&gt;

&lt;p&gt;The key takeaway here is that learning complex concepts and embedding them in your memory takes time and effort. We might be able to develop simple skills without constantly referring to guides, thanks to trial and error and the valuable insights provided by StackOverflow. But for profound understanding and long-term retention, patience and repetition are essential.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ACsp26Cn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631883593839/VqCrGL8T5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ACsp26Cn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631883593839/VqCrGL8T5.png" alt="image.png" width="600" height="456"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Learning one thing at a time
&lt;/h2&gt;

&lt;p&gt;As software developers, we reside in an industry that incessantly evolves, forcing us to adapt and acquire a broad range of skills. I love learning new things and experiencing that invigorating feeling when reading a paragraph that resonates with me. However, I must admit that what I find captivating today may be forgotten tomorrow.&lt;/p&gt;

&lt;p&gt;That's why I recommend, not only to others but to myself as wellthe one who often needs the reminder the mostto focus on learning one thing at a time. Dedicate a week to mastering a small, specific concept, such as Data Transfer Objects (DTOs) in Java. Once you've learned this concept, consider writing an article about it. Feel free to visit the article whenever you have doubts or need a refresher.&lt;/p&gt;

&lt;p&gt;For more complex subjects, like a cloud certification, break it down into manageable concepts. Let's say you plan to complete the certification within two months. Divide your time accordingly and dedicate each week to learning a specific service, following the provider's guide.&lt;/p&gt;

&lt;p&gt;Read articles, engage in hands-on labs, write about your experiences, and repeat this process.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;When you test your knowledge, rest assured that you'll have a solid understanding of the material.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;In conclusion, writing enhances the learning process. This is not just a casual claim, but a fact. Let's recap the key points that illustrate the importance of technical writing for developers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Traditional memorization-based learning methods fall short.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Profound understanding is crucial for effectively applying complex concepts.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Writing requires explaining, which reinforces understanding.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Passive learning (reading, watching) is not as effective as active learning (coding, writing).&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Attempting tutorials in different programming languages or approaching the same problem from a different perspective increases comprehension.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;We can revisit articles, but we can't revisit our fleeting thoughts.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Focus on learning one thing at a time for better retention.&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you've reached this point, I am honored by your commitment. Thank you for reading and considering the significance of technical writing for learning as a developer.&lt;/p&gt;

&lt;p&gt;Reach out on &lt;a href="https://twitter.com/VictorGarciaDev"&gt;Twitter&lt;/a&gt; to find more valuable content or just chat!&lt;/p&gt;

&lt;p&gt;🐦 &lt;a class="mentioned-user" href="https://dev.to/victorgarciadev"&gt;@victorgarciadev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;😼 &lt;a href="https://github.com/victorgrubio"&gt;Github&lt;/a&gt;&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.worklearning.com/2006/05/01/people_remember/"&gt;People remember 10%, 20%Oh Really?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>writing</category>
      <category>technicalwriting</category>
      <category>learning</category>
      <category>development</category>
    </item>
    <item>
      <title>Why Writing Helps You Learn</title>
      <dc:creator>Victor Garcia Dev</dc:creator>
      <pubDate>Fri, 17 Sep 2021 13:40:01 +0000</pubDate>
      <link>https://dev.to/victorgarciadev/why-writing-helps-you-learn-1ap1</link>
      <guid>https://dev.to/victorgarciadev/why-writing-helps-you-learn-1ap1</guid>
      <description>&lt;p&gt;Many of you may have tried to start technical writing and left it after a week.&lt;/p&gt;

&lt;p&gt;Maybe someone has created a blog but stopped posting after a year or so.&lt;/p&gt;

&lt;p&gt;You could have thought: "Why would I spent time writing for free if I don't like it so much. I should see another YT tutorial about this random topic"&lt;/p&gt;

&lt;p&gt;Maybe you have wondered: "Would I be the one that replies in StackOverflow one day?"&lt;/p&gt;

&lt;p&gt;Some of you may feel identified by these sentences. I will try to explain to you my main motivation to start writing:&lt;/p&gt;

&lt;blockquote&gt;
&lt;h3&gt;
  
  
  Writing makes me learn better!
&lt;/h3&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  Traditional learning methods SUCKS!
&lt;/h2&gt;

&lt;p&gt;As someone that comes from college here in Spain, I had to learn tons of things in a small amount of time. When the tests came, I could find myself with 8 exams in 4 days. This is Telecommunications Engineering we are talking about. Not an easy thing.&lt;/p&gt;

&lt;p&gt;What would I do? What I have been educated for: Try to learn how to do some exercises from previous years. Memorize the parts that are always asked the same way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--dwzbQWj5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631884055242/v5Tc1M-O6.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--dwzbQWj5--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631884055242/v5Tc1M-O6.jpeg" alt="tony-tran-F8sCVSW4t4E-unsplash (1).jpg" width="640" height="960"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;It worked for 4 years!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When I arrived at my Machine Learning master's, I had to change. The math was the most complex I have seen in my life. Thanks to an awesome set of teachers, I STARTED to focus on understanding things in depth. The knowledge I have acquired during that year is one of the most durable I can account for.&lt;/p&gt;

&lt;h3&gt;
  
  
  Here is when everything started to make sense.
&lt;/h3&gt;




&lt;h2&gt;
  
  
  Overcome the "Tutorial Syndrome"
&lt;/h2&gt;

&lt;p&gt;We are born in the Youtube era. We have seen an incredible amount of videos for many topics to find a solution. A lot of content creators, almost infinite knowledge at hand ... But let me ask you a question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;How much of this content did you remember after 3 days?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I will love to have some feedback in the comments. For me, almost nothing. Don't get me wrong. I love YT and it has brought amazing content to our lives for free.&lt;/p&gt;

&lt;p&gt;But watching videos, reading books, posts ... IT'S ALL PASSIVE!&lt;/p&gt;

&lt;p&gt;It requires a lot less attention than coding, for example. In my experience, I could think of a couple of concepts extracted from books. I was amazed by the information. It released all the dopamine it could.&lt;/p&gt;

&lt;p&gt;Most of the time, every highlight in a book is forgotten. Lines of CODE and TEXT, created with BLOOD and SWEAT, usually aren't.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/l4FATJpd4LWgeruTK/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/l4FATJpd4LWgeruTK/giphy.gif" alt="sweating.gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Increase understanding of topics
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;If you could name a topic that writing didn't help you to understand better, I am a living lie.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Here I will use an example of my own experience. I was reading "Head First Design Patterns". Recommendable by the way. In this book, one or more &lt;a href="https://en.wikipedia.org/wiki/Software_design_pattern"&gt;Design Patterns&lt;/a&gt; are introduced and explained in each chapter. I was reading it almost every day, but after a week I thought: "Okay, I did not remember any pattern. I don't know how to apply them"&lt;/p&gt;

&lt;p&gt;So I decided: "Let's code them in a different language". Book examples were in Java, so for me, the obvious pick was Python.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;IT TOOK ME 3 DAYS to make the &lt;a href="https://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm"&gt;Abstract Factory&lt;/a&gt; work! 😅&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Don't have any doubt about this: I freaking know how to implement the abstract factory after that. And also learn how to model a pizza franchise business 😆&lt;/p&gt;

&lt;p&gt;What I want you to see with this is: Learning things that perdure in your memory takes time! Probably, the complex things that you can do without checking a guide are built on multiple failed attempts and StackOverflow questions.&lt;/p&gt;

&lt;p&gt;I will show you a graphic about the retention of information based on the channel it is acquired after 2 weeks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ACsp26Cn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631883593839/VqCrGL8T5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ACsp26Cn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn.hashnode.com/res/hashnode/image/upload/v1631883593839/VqCrGL8T5.png" alt="image.png" width="600" height="456"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Learning one thing at a time
&lt;/h2&gt;

&lt;p&gt;As software developers, we live in an industry that is constantly evolving. We are required to manage a lot of tools. This urges us to learn a lot of different things. For so much time we lose focus.&lt;/p&gt;

&lt;p&gt;I love to learn new things. I love that sensation of reading a paragraph and say: "My god, this is great to know". Does Victor remember next month? Of course not.&lt;/p&gt;

&lt;p&gt;I recommend everyone, including myself (the one that needs it the most): One thing at a time. Let's spend a week learning a small concept, let say: DTOs in Java. If we learn them for a week, write an article about it. You could visit it if you have any doubts!&lt;/p&gt;

&lt;p&gt;If you plan to learn something more complex, divide it and make it easier. A cloud certification for example. Let's say we plan to make it in 2 months.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Divide it into concepts by the guides of the provider and learn a service per week or so.&lt;/li&gt;
&lt;li&gt;Read articles &lt;/li&gt;
&lt;li&gt;Make labs&lt;/li&gt;
&lt;li&gt;Write about the labs&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you make the sample tests, I am sure you will understand everything.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;PD: Skin in the game. I will try to do this for my next cloud certs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Writing improves learning. This is &lt;strong&gt;FEKTS&lt;/strong&gt;. The main points explain to defend this have been:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Traditional methods for learning with memorization do not work&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Complex concepts need deep understanding to be used&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Writing requires explaining. Explaining requires understanding&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Passive learning (Reading, Watching) vs Active learning (Coding, Writing)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Try to code the tutorial in a different programming language. Or model the same problem differently for the same one&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;An article can be revisited. A thought can't&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learning one thing at a time&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;I am HONOURED if you have reached this point. Thanks a lot for reading 💙&lt;/p&gt;

&lt;p&gt;Hopefully, I was able to illustrate how technical writing is important for learning as developers.&lt;/p&gt;

&lt;p&gt;Reach out on &lt;a href="https://twitter.com/VictorGarciaDev"&gt;Twitter&lt;/a&gt; to find more valuable content or just chatting!&lt;/p&gt;

&lt;p&gt;🐦 &lt;a class="mentioned-user" href="https://dev.to/victorgarciadev"&gt;@victorgarciadev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;😼 &lt;a href="https://github.com/victorgrubio"&gt;https://github.com/victorgrubio&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.worklearning.com/2006/05/01/people_remember/"&gt;People remember 10%, 20%…Oh Really?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks and Keep It Up! 🦾🦾&lt;/p&gt;

</description>
      <category>career</category>
      <category>writing</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
