<?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>Forem: Yari Antonieta</title>
    <description>The latest articles on Forem by Yari Antonieta (@yaariii3).</description>
    <link>https://forem.com/yaariii3</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%2F223733%2Ffef6eb52-d2d7-4e4c-abb4-2980a503236c.jpg</url>
      <title>Forem: Yari Antonieta</title>
      <link>https://forem.com/yaariii3</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/yaariii3"/>
    <language>en</language>
    <item>
      <title>NodeJs Layered Architecture</title>
      <dc:creator>Yari Antonieta</dc:creator>
      <pubDate>Mon, 04 Oct 2021 14:30:23 +0000</pubDate>
      <link>https://forem.com/yaariii3/nodejs-layered-architecture-4gk7</link>
      <guid>https://forem.com/yaariii3/nodejs-layered-architecture-4gk7</guid>
      <description>&lt;p&gt;Something that was not intuitive to me when I was getting into this software development world was how to build the software's architecture. Sure, I understood how to write functions, and components but optimally organizing them was not something I learned alone.&lt;/p&gt;

&lt;p&gt;Some time ago, I was assigned the task to refactor the NodeJS codebase architecture into layered architecture. I didn't have any idea what layered architecture was or how it looked like. So I DuckDuckGoed and Googled search and quickly noticed a couple of blog posts about layered architecture but not actual code examples. So I'm providing a before and after layered architecture example based on what I learned!&lt;/p&gt;

&lt;p&gt;Before going into this software architecture journey, let's understand &lt;em&gt;what&lt;/em&gt; layered architecture is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Layered Architecture?
&lt;/h2&gt;

&lt;p&gt;A pattern used in software development where roles and responsibilities within the application (app) are separated into layers. Per &lt;a href="https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html" rel="noopener noreferrer"&gt;Chapter 1: Layered Architecture from Software Architecture Patterns by Mark Richards&lt;/a&gt;: &lt;em&gt;"Each layer in the architecture forms an abstraction around the work that needs to be done to satisfy a particular business request."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So, one of layered architecture's goals is to separate concerns among components. Another goal is to organize layers so they can perform a specific role within the app.&lt;/p&gt;

&lt;p&gt;A small app consists of three (3) layers: Router Layer, Service Layer, and Data Access Layer (DAL). The number of layers will depend on how complex your app turns out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Router Layer&lt;/strong&gt; contains the app programming interface (API) routes of the app. Its only job is to return a response from the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Service Layer&lt;/strong&gt; handles the business logic of the app. This means that data is transformed or calculated to meet the database model's requirements before being sent to the server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Data Access Layer (DAL)&lt;/strong&gt; has access to the database to create, delete, or edit data. It is where all the request and response from server logic is handled. If there is no database connected directly into the app, this layer may include Hypertext Transfer Protocol or http requests to the server.&lt;/p&gt;

&lt;p&gt;A key concept of the architecture layer is &lt;em&gt;how&lt;/em&gt; data move between layers. To understand this movement, let's look at the diagram below for reference.&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%2Fctrly.blog%2Fwp-content%2Fuploads%2F2021%2F03%2Flayers-1-1024x763.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%2Fctrly.blog%2Fwp-content%2Fuploads%2F2021%2F03%2Flayers-1-1024x763.png" alt="NodeJs Layered Architecture diagram"&gt;&lt;/a&gt;Layered architecture diagram&lt;/p&gt;

&lt;h2&gt;
  
  
  Moving between Layers
&lt;/h2&gt;

&lt;p&gt;The data journey starts at the presentation layer once the user clicks a button. The click triggers a function that sends the API's data request, located at the router layer. The router layer method calls a component located at the service layer, and its concern is to wait for the service layer's response to return it.&lt;/p&gt;

&lt;p&gt;At the service layer, the data is transformed or calculated. Hypothetically, if a user must reset their password every 90 days, it's here at the service layer, where the calculations are done before passing the results to the server.  After transformation, the service layer component calls an injected DAL component, and the data is passed into the DAL.&lt;/p&gt;

&lt;p&gt;Finally, the data request is made to the database at the DAL. The DAL is structured as a request inside a promise, the promise being resolved with the database's response.&lt;/p&gt;

&lt;p&gt;When the DAL promise resolves with the database's response, the response returns to the service layer, which then the service layer itself returns to the router layer. When the response reaches the router layer, the data reaches the user back at the presentation layer.&lt;/p&gt;

&lt;p&gt;It is crucial to understand that the data moves from one layer to another layer without skipping layers in between. The data request moves from the router layer to the service layer and then to the DAL.&lt;/p&gt;

&lt;p&gt;Later, the response is returned from the DAL to the service layer, and finally, to the router layer. Neither the request nor the response goes from the router layer to the DAL layer or from the DAL layer to the router layer.&lt;/p&gt;

&lt;p&gt;Now that we understand &lt;em&gt;what&lt;/em&gt; layered architecture software is, let's learn how layered architecture was implemented. Let's use, as a reference, the action of updating a profile to illustrate software before and after layered architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Layered Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Before Layered Architecture Implementation
&lt;/h3&gt;

&lt;p&gt;Let's begin with the file structure &lt;strong&gt;before&lt;/strong&gt; implementing the layered architecture.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-project/
├── node_modules/
├── config/
│   ├── utils.js
├── components/
├── pages/
│   ├── profile.js
│   ├── index.js
├── public/
│   ├── styles.css
├── routes/
│   ├── alerts.js
│   ├── notifications.js
│   ├── profile.js
│   ├── index.js
├── app.js
├── routes.js
├── package.json
├── package-lock.json
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;strong&gt;pages / profile.js&lt;/strong&gt; directory contains the front-end code for the user profile. It's here where the user interaction triggers the data trajectory to the server and back. Even though this directory doesn't contain NodeJs code, it's important to understand when NodeJs interacts with the app's front end side.&lt;/p&gt;

&lt;p&gt;For this example, the front-end is written with the ReactJs framework.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Profile = ({ user }) =&amp;gt; {
  // User prop is destructured
  const { id, name, lastname, email } = user;
  // Form states are initialized with user prop's information
  const [nameState, handleName] = useState(`${name}`);
  const [lNameState, handleLName] = useState(`${lastname}`);
  const [emailState, handleEmail] = useState(`${email}`);
  // Url that sends request to api
  const url = `profile/update/${id}`;

  return (
    &amp;lt;form
      action={url}
      method="post"
      style={{ display: 'flex', flexDirection: 'column' }}
    &amp;gt;
      &amp;lt;input
        placedholder="Name"
        value={nameState}
        onChange={handleName}
        type="text"
        name="name"
      /&amp;gt;
      &amp;lt;input
        placedholder="Last Name"
        value={lNameState}
        onChange={handleLName}
        type="text"
        name="lastname"
      /&amp;gt;
      &amp;lt;div style={{ display: 'flex', flexDirection: 'row' }}&amp;gt;
        &amp;lt;input
          placedholder="Email"
          value={emailState}
          onChange={handleEmail}
          required
          type="email"
          name="email"
        /&amp;gt;
        &amp;lt;button type="submit"&amp;gt;
          Save
        &amp;lt;/button&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/form&amp;gt;
  );
};

export default Profile;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The code above is the entry point where the end-user interacts with the app. It's a form that includes text inputs for the name, last name, and email and a "save" button.&lt;/p&gt;

&lt;p&gt;The user types inside the text input the information described by the placeholder. Later, the user saves her/his/their information for future reference by clicking the "save" button. When the "save" button is clicked, it triggers a POST routing method that sends the user data to the Uniform Resource Locator, or URL, passed into the method.&lt;/p&gt;

&lt;p&gt;Before implementing the layered architecture, the codebase I encountered included all the app routing methods inside the directory &lt;strong&gt;my-project / routes.js&lt;/strong&gt;. It looked similar to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = (app, routes) =&amp;gt; {
  // Profile
  app.get('/profile/:id/:message?', routes.profile.details);
  app.post('/profile/new/:page?, routes.profile.create);
  app.post('/profile/update/:id/:page?', routes.profile.update);
  app.post('/profile/delete/:id', routes.profile.delete);

  // Notifications
  app.get('/notifications', routes.notifications.add);
  app.post('/notifications/send/:message?', routes.notifications.send);

  // Alerts
  app.get('/alerts/breaking', routes.alerts.read);
  app.post('/alerts/breaking', routes.alerts.send);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By keeping all the routing methods in the same directory, this codebase may introduce compiling errors or software bugs between components that, normally, wouldn't interact between themselves.&lt;/p&gt;

&lt;p&gt;Each routing method requires three parameters: 1) route, 2) authentication and, 3) request/response method. The request/response method sends and receives the data request to the server.&lt;/p&gt;

&lt;p&gt;Another detail worth highlighting about the codebase before implementing layered architecture is that the request/response methods for the profile component were defined within the &lt;strong&gt;routes / profile.js&lt;/strong&gt; directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const moment = require('moment');
const apiUrl = require('../config/constants').API_URL;
const baseApiUrl = `${apiUrl}`;

const profile = {
    details: (req, res) =&amp;gt; {
        const { id } = req.params;

        request({
            uri: `${baseApiUrl}/${id}`,
            method: 'GET',
            json: true,
        }, (err, r, body) =&amp;gt; {
            const { id, name, lastname, email } = body;
            const info = {
                id,
                name,
                lastname,
                email,
            };

            if (err || r.statusCode !== 200) {
                res.status(400).json({
                    error: err || r.statusCode
                });
                return null;
            }
            res.json({
                status: 'success',
                post: info,
            });
        });
    },

    create: (req, res) =&amp;gt; {
        const { id, name, lastname, email } = req.body;
        const createDate = moment().format();
        const info = {
            id,
            name,
            lastname,
            email,
            createDate,
        };

        request({
            uri: `${baseApiUrl}`,
            method: 'POST',
            body: info,
            json: true,
        }, (err, r, body) =&amp;gt; {
            if (err || r.statusCode !== 201) {
                res.status(400).json({
                    error: err || r.statusCode
                });
                return null;
            }
            res.json({
                status: 'success',
                post: body,
            });
        });
    },

    update: (req, res) =&amp;gt; {
        const { id, name, lastname, email } = req.body;
        const updateDate = moment().format();
        const info = {
            name,
            lastname,
            email,
            updateDate,
        };

        request({
            uri: `${baseApiUrl}/${id}`,
            method: 'PUT',
            body: info,
            json: true,
        }, (err, r, body) =&amp;gt; {
            if (err || r.statusCode !== 200) {
                res.status(400).json({
                    error: err || r.statusCode,
                    statusText: err || body.message,
                });
                return null;
            }
            res.json({
                status: 'success',
                post: body,
            })
        });
    },

    delete: (req, res) =&amp;gt; {
        const { id } = req.params;

        request({
            uri: `${baseApiUrl}/${id}`,
            method: 'DELETE',
            json: true,
        }, (err, r, body) =&amp;gt; {
            if (err || r.statusCode !== 200) {
                res.status(400).json({
                    error: err || r.statusCode
                });
                return null;

            }
            res.json({
                success: 'OK',
            });
        });
    },
}

module.exports = profile;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how, in the create and update methods, data is being transformed by creating a new object with specific key names and values. This includes the &lt;em&gt;creation date&lt;/em&gt; and &lt;em&gt;update date&lt;/em&gt; timestamps values added at the create and update methods. Timestamps are included, so they comply with the server's data models.&lt;/p&gt;

&lt;p&gt;Right after data transformation, there is an http  request to the server. Whatever the server response is, the response is sent back to the front-end in JSON format. So, this codebase handles the business logic and server access at the same layer.&lt;/p&gt;

&lt;p&gt;Overall, the before mentioned code base mixed too many concerns between layers of work. At the routing layer, components that &lt;em&gt;do not&lt;/em&gt; interact between themselves throughout the app are handled together. While business logic and server requests are also handled together.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layered Architecture Implementation
&lt;/h3&gt;

&lt;p&gt;Recalling the objectives for layered architecture, it's important to separate concerns among components. Also, layers must perform a specific role within the app.&lt;/p&gt;

&lt;p&gt;To separate concerns, I created a module for profile, notification, and for alerts. Inside each module, I created the three layers: 1) Router layer that includes all the routing method for the specific module, 2) Service layer that includes business logic components, and 3) DAL that includes the server request and response method.&lt;/p&gt;

&lt;p&gt;Below is an example of the file structure considering layered architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;my-project/
├── node_modules/
├── config/
│   ├── utils.js
├── components/
├── modules/
│   │   ├── profile/
│   │   │   ├── routesProfile.js
│   │   │   ├── serviceProfile.js
│   │   │   ├── dalProfile.js
│   │   │   ├── index.js
│   │   ├── notification/
│   │   │   ├── routesNotification.js
│   │   │   ├── serviceNotification.js
│   │   │   ├── dalNotification.js
│   │   │   ├── index.js
│   │   ├── alerts/
│   │   │   ├── routesAlert.js
│   │   │   ├── serviceAlert.js
│   │   │   ├── dalAlert.js
│   │   │   ├── index.js
├── pages/
│   ├── profile.js
│   ├── index.js
├── public/
│   ├── styles.css
├── app.js
├── routes.js
├── package.json
├── package-lock.json
└── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same as &lt;em&gt;before&lt;/em&gt; implementation, the front-end side triggers the routing method.&lt;/p&gt;

&lt;p&gt;Instead of having all the routing methods from the app in &lt;strong&gt;my-project/routes.js&lt;/strong&gt;, I: &lt;/p&gt;

&lt;p&gt;1) Imported all modules indexes in &lt;strong&gt;my-project/routes.js&lt;/strong&gt;. An example of &lt;strong&gt;modules/ profile / index.js&lt;/strong&gt; below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Inside modules/profile/index.js

const profileService = require('./profileService');
const profileRoutes = require('./profileRoutes');

module.exports = {
  profileService,
  profileRoutes,
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2) Called routing layer.&lt;/p&gt;

&lt;p&gt;3) Pass each module into its routing layer. Example below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Inside my-projects/routes.js
const profile = require('./modules/profile/index');
const alert = require('./modules/alert/index');
const notification = require('./modules/notification/index');

module.exports = (
  app,
) =&amp;gt; {

  profile.profileRoutes(app, profile);
  alert.alertasRoutes(app, alert);
  notification.notificationRoutes(app, notification);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look how clean the &lt;strong&gt;my-project/routes.js&lt;/strong&gt; is! Instead of handling all the app's routing methods, we call the module's routing layer. In this case, the profile module.&lt;/p&gt;

&lt;p&gt;The front-end triggers a call to &lt;strong&gt;profile.profileRoutes(app, profile)&lt;/strong&gt; to access all the routing methods regarding the profile component.&lt;/p&gt;

&lt;h4&gt;
  
  
  Routing Layer
&lt;/h4&gt;

&lt;p&gt;Here is an example of how I wrote the routing layer for the profile module.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Inside modules/profile/routingProfile.js

module.exports = (app, routes) =&amp;gt; {
// Route for get profile details
app.get('/profile/:id/:message?', 
   async (req, res) =&amp;gt; {
    const { params} = req;
    const { id } = params;
    try {
      const details = await 
        profile.profileService.getProfileDetails(id);
      res.json(details);
    } catch (error) {
      res.json({ status: 'error', message: error.message });
    }
});

// Route for post create profile
app.post('/profile/new/:page?',
  async (req, res) =&amp;gt; {
    const { body} = req;
    try {
      const new = await 
        profile.profileService.postCreateProfile(body);
      res.json(new);
    } catch (error) {
      res.json({ status: 'error', message: error.message });
    }
});

// Route for post update profile
app.post('/profile/update/:id/:page?', async (req, res) =&amp;gt; {
    const { body, params} = req;
    const { id } = params;

    try {
      const update = await 
        profile.profileService.postUpdateProfile(id, body);
      res.json(update);
    } catch (error) {
      res.json({ status: 'error', message: error });
    }
  });

// Route for post delete profile
app.post('/profile/delete/:id', 
  async (req, res) =&amp;gt; {
    const { params } = req;
    const { id } = params;
    try {
        const delete = await 
          profile.profileService.postDeleteProfile(id);
        res.json(delete);
      } catch (e) {
        res.json({ status: 'error', error: e });
      }
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice how the routing method calls the corresponding service layer method and waits for its response. Also, notice how that's the routing layer's only job.&lt;/p&gt;

&lt;p&gt;Let's recall that the &lt;strong&gt;URL&lt;/strong&gt; valued triggered from the front-end when the user's clicked the "update" button is "/profile/update/:id/." The routing layer will have to wait for &lt;strong&gt;postUpdateProfile()&lt;/strong&gt; method's response at the service layer to finish its work.&lt;/p&gt;

&lt;p&gt;Now that the service layer is called let's see how I wrote the profile module's service layer.&lt;/p&gt;

&lt;h4&gt;
  
  
  Service Layer
&lt;/h4&gt;

&lt;p&gt;An example of the service layer I wrote below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const moment = require('moment');
const { API_URL } = require('../../config/constants');

const baseApiUrl = `${API_URL}`;
const profileDal = require('./profileDal')();

const profileService = {
  /**
   * Gets profile detail
   * @param {String} id - profile identification number
   */
  getDetailProfile: (id) =&amp;gt; profileDal.getDetailProfile(id, token),

  /**
   * Creates profile
   * @param {Object} body - profile information
   */
  postCreateProfile: (body) =&amp;gt; {
    const { name, lastname, email } = body;
    const createDate = moment().format();
    const profile = {
      name,
      lastname,
      email,
      createDate,
    };
    return profileDal.postCreateProfile(profile);
  },

  /**
   * Updates profile
   * @param {String} id - profile identification number
   * @param {Object} body - profile information
   */
  postUpdateProfile: (id, body) =&amp;gt; {
    const { name, lastname, email } = body;
    const updateDate = moment().format();
    const data = {
      name,
      lastname,
      email,
      updateDate,
    };

    return profileDal.postUpdateProfile(id, data);
  },

  /**
   * Deletes the selected profile
   * @param {String} id - profile identification number
   */
  postDeleteProfile: (id) =&amp;gt; profileDal.postDeleteProfile(id),
};

module.exports = profileService;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This layer is specific to business logic for the profile module. It focuses on transforming the data, so it complies with the request method's data models.&lt;/p&gt;

&lt;p&gt;So, if the data model requires a timestamp to create and update data, it's here where you may want to include that data. See &lt;strong&gt;postUpdateProfile()&lt;/strong&gt; above for example.&lt;/p&gt;

&lt;p&gt;You can also validate data in the service layer. Validating data in this layer guarantees that the DAL will receive the data as needed and that its only job will be to send data to the middleware or server. Furthermore, validating data in the service layer allows the DAL to be used by multiple modules with different validation requirements.&lt;/p&gt;

&lt;p&gt;The DAL is injected in this layer to be called within every method in this layer. The results of the data transformation are passed into the DAL to be sent to the server.&lt;/p&gt;

&lt;h4&gt;
  
  
  Data Access Layer
&lt;/h4&gt;

&lt;p&gt;The DAL I wrote for the profile module is something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const request = require('request');
const { API_URL } = require('../../config/constants');

const baseApiUrl = `${API_URL}`;

module.exports = () =&amp;gt; ({
  /**
   * Gets profile details
   * @param {String} id - profile id
   */
  getDetailProfile: (id) =&amp;gt; new Promise((resolve, reject) =&amp;gt; {
    request({
      uri: `${baseApiUrl}/${id}`,
      method: 'GET',
      json: true,
    }, (err, r, body) =&amp;gt; {
      const { id, name, lastname, email } = body;
      const profile = {
        id,
        name,
        lastname,
        email,
      };

      if (err || r.statusCode !== 200) {
        return reject(err);
      }
      return resolve({
        status: 'success',
        profile,
      });
    });
  }),

  /**
   * Creates new profile
   * @param {Object} body - profile information
   */
  postCreateProfile: (body) =&amp;gt; new Promise((resolve, reject) =&amp;gt; {
    request({
      uri: baseApiUrl,
      method: 'POST',
      body,
      json: true,
    }, (err, r, b) =&amp;gt; {
      if (err || r.statusCode !== 201) {
        return reject(err);
      }
      return resolve(b);
    });
  }),

  /**
   * Updates profile
   * @param {String} id - profile id
   * @param {Object} body - profile information
   */
  postUpdateProfile: (id, body) =&amp;gt; new Promise((resolve, reject) =&amp;gt; {
    request({
      uri: `${baseApiUrl}/${id}`,
      method: 'PUT',
      body,
      json: true,
    }, (err, r, b) =&amp;gt; {
      if (err || r.statusCode !== 200) {
        return reject(err);
      }

      return resolve({
        status: 'success',
        post: b,
      });
    });
  }),

  /**
   * Deletes profile
   * @param {String} id - profile id
   */
  postDeleteProfile: (id, token) =&amp;gt; new Promise((resolve, reject) =&amp;gt; {
    request({
      uri: `${baseApiUrl}/${id}`,
      method: 'DELETE',
      json: true,
    }, (err, r) =&amp;gt; {
      if (err || r.statusCode !== 200) {
        return reject(err);
      }
      return resolve({ status: 'OK' });
    });
  }),
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The DAL methods receive variables from the service layer. These variables are required for http requests. When the http request is triggered by receiving the service layer's variables, it dispatches a promise that is expected to resolve with an object. The object is defined after the server response is available.&lt;/p&gt;

&lt;p&gt;If the request is successful, the DAL promise is resolved with an object that returns to the service layer, which itself returns to the routing layer. When the routing layer receives the object returned by the service layer, the routing layer sends the object in JSON format to the front-end.&lt;/p&gt;

&lt;p&gt;And that, my friends, is how I implemented layered architecture for a NodeJs code base. I know that it looks like a lot of work, but I did learn so much about this codebase after this project that I feel completely comfortable implementing or fixing things.&lt;/p&gt;

&lt;p&gt;Thank you so much for reading this far!&lt;/p&gt;

&lt;h2&gt;
  
  
  By the Way
&lt;/h2&gt;

&lt;p id="bytheway"&gt;I wrote a lot of this article listening to the &lt;a href="https://open.spotify.com/playlist/4zgePELlX9cYOoYadGbazb?si=P6xmJx_LTJiwhkVGyYc8sQ" rel="noreferrer noopener"&gt;Afro House Spotify playlist&lt;/a&gt;. A great playlist for banging your head while writing.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://open.spotify.com/embed/playlist/4zgePELlX9cYOoYadGbazb" width="100%" height="380px"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;small&gt;&lt;em&gt;&lt;a href="https://ctrly.blog/nodejs-layered-architecture/" rel="noopener noreferrer"&gt;This article&lt;/a&gt; was originally posted on &lt;a href="https://ctrly.blog/" rel="noopener noreferrer"&gt;ctrl-y blog&lt;/a&gt;. Also, you can find a &lt;a href="https://ctrly.blog/es/arquitectura-capas/" rel="noopener noreferrer"&gt;Spanish version of this article&lt;/a&gt; in &lt;a href="https://ctrly.blog/es/" rel="noopener noreferrer"&gt;ctrl-y blog/es&lt;/a&gt;.&lt;/em&gt;&lt;/small&gt;&lt;/p&gt;

</description>
      <category>architecture</category>
      <category>beginners</category>
      <category>tutorial</category>
      <category>node</category>
    </item>
    <item>
      <title>What is the Rendering Engine?</title>
      <dc:creator>Yari Antonieta</dc:creator>
      <pubDate>Tue, 16 Jun 2020 20:30:56 +0000</pubDate>
      <link>https://forem.com/yaariii3/what-is-the-rendering-engine-5hec</link>
      <guid>https://forem.com/yaariii3/what-is-the-rendering-engine-5hec</guid>
      <description>&lt;h4&gt;
  
  
  &lt;em&gt;&lt;a href="https://ctrly.blog/what-is-the-rendering-engine/"&gt;This article&lt;/a&gt; was originally posted on &lt;a href="https://ctrly.blog/"&gt;ctrl-y blog&lt;/a&gt;. Also, you can find a &lt;a href="https://ctrly.blog/es/que-es-el-motor-de-renderizado/"&gt;Spanish version of this article&lt;/a&gt; in &lt;a href="https://ctrly.blog/es/"&gt;ctrl-y blog/es&lt;/a&gt;.&lt;/em&gt;
&lt;/h4&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;On the Side Note section at the end of each article, I like to share what I was listening to while writing machine or human words. I ❤️ music so I spend time (sometimes a bit too much) searching for, or creating, long playlists so I can listen to them while I'm working.&lt;/em&gt;
&lt;/h4&gt;



&lt;p&gt;Recently, I was hearing the &lt;a href="https://www.ladybug.dev/episodes/level-up-javascript"&gt;Ladybug’s Podcast episode: “Level Up with Javascript”&lt;/a&gt; were one of the podcasts’ host resumed how the web browser works. She explained it so helpful and straightforward that it picked my curiosity into searching a bit more about the topic.&lt;/p&gt;

&lt;p&gt;The Ladybugs suggested some resources, so I followed suit. And wow, I had not appreciated the processes that occur between ‘Saving’ my front-end code and observe my code elements on the screen.&lt;/p&gt;

&lt;p&gt;The rendering engine is one of the basic components of a web browser. It’s responsible for interpreting the HTML (Hypertext Markup Language), CSS (Cascading Style Sheets), and Javascript files to present (render) them on screen, in other words, convert them to pixels.&lt;/p&gt;

&lt;p&gt;The process that goes from interpreting HTML, CSS, and Javascript to pixel conversion can be grouped in 4 (four) general steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parsing of the HTML document to DOM (Document Object Model).&lt;/li&gt;
&lt;li&gt;CSS file interpretation (CSSOM – Cascading Style Sheets Object Model) for each of the DOM nodes.&lt;/li&gt;
&lt;li&gt;Creation of the new tree that includes the DOM, and each node’s style and layout.&lt;/li&gt;
&lt;li&gt;A render tree is rendered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But, before we go any further with a web browser’s render tree, have you ever participated, or seen, a sports game where fans of a team sing while a visual shows as big as the dimensions of a public sector? The following image is an example of what I am talking about.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NXVufTlm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/05/sport-chant.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NXVufTlm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/05/sport-chant.png" alt="'word-press image"&gt;&lt;/a&gt;&lt;/p&gt;
Credit: Scene from a Youtube video recorded by the user &lt;a href="https://www.youtube.com/channel/UCPBOvCtgSUuCjMsfOndtWHQ"&gt;barcelona.jp&lt;/a&gt;



&lt;p&gt;Why the question?&lt;/p&gt;

&lt;p&gt;Because I am going to explain how the rendering engine of the browser works similarly as a stadium filled with people that together, they illustrate a message while they chant to their favorite team.&lt;/p&gt;

&lt;p&gt;Disclaimer: To use a sports event as an example will result in a limitation of a detailed explanation. So, I will explain the details of certain processes in separate articles. This will help to maintain this article short, and prevent you from getting bored of reading me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Parsing: HTML to DOM
&lt;/h2&gt;

&lt;p&gt;Web browsers do not interpret HTML files the same as programmers write them. That is why the rendering engine is in charge of parsing (analyze and separate) the HTML structure into objects that the browser can read.&lt;/p&gt;

&lt;p&gt;The rendering engine receives the HTML files as a stadium receives sports fans waiting in line. With lots of people entering consecutively but the stadium does not understand how does each fan group relates to one another or how are they going to be seated.&lt;/p&gt;

&lt;p&gt;That’s what the stadium staff is for. They can read each person’s ticket and direct them to their respective chair to structure the team visual that will be seen during the game.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Q94g4qmeD3RpomVN17/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Q94g4qmeD3RpomVN17/giphy.gif" alt="ctrly-giphy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When browsers parse, they consider the HTML tags, and how they are nested, to create objects and relate them, including the DOM (Document Object Model).&lt;/p&gt;

&lt;p&gt;The DOM is a document that models the relationship between the different objects, or nodes, that structure the web page.&lt;/p&gt;

&lt;p&gt;The document model can be manipulated using Javascript. Some manipulation examples include adding nodes and changing node colors.&lt;/p&gt;

&lt;p&gt;The process of creating these objects is more complex, so I will not be detailing the process in this article. But, by this point, the DOM knows how the web page will be structured. Although it still has not interpreted how the web page will be styled or laid out.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/kz13G1z81S3Euxcfvq/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/kz13G1z81S3Euxcfvq/giphy.gif" alt="ctrly-giphy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On our sports fan example, by this point, each fan group has entered the stadium and are seated. But, they still do not have the colored cardboard they are going to display during the chant.&lt;/p&gt;

&lt;h2&gt;
  
  
  CSSOM Construction
&lt;/h2&gt;

&lt;p&gt;Ten (10) minutes before the game starts, the stadium staff with lots of colored cardboard on hand, begin to walk to each corner of the seated rows.&lt;/p&gt;

&lt;p&gt;Each cardboard has a seat number assigned, so the visual, at large, makes sense. Let’s say that each carton was appointed to a specific chair by a style calculation.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/XHG3VRtrigVRC3eLxk/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/XHG3VRtrigVRC3eLxk/giphy.gif" alt="ctrly-giphy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After converting the HTML into the DOM, the render engine assigns the styles described in the CSS file to each DOM node. This assignment is known as CSS style computation. This process includes selector pairing and style cascading process (hence the name Cascading Style Sheets).&lt;/p&gt;

&lt;p&gt;CSS style computation is a topic that can take up to an entire article, so I will not inquire about that in this article. But, for the sake of this article, it is essential to know that during this stage, the rendering engine assigns styles to each DOM node like color, font, and border.&lt;/p&gt;

&lt;p&gt;When DOM nodes are assigned a style, it constructs a new tree. This tree is called the CSSOM (Cascading Style Sheets Object Model).&lt;/p&gt;

&lt;p&gt;Up to this point, the rendering engine knows the page's structure and each element’s style.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/WrxsB8YoqwQVot2uhi/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/WrxsB8YoqwQVot2uhi/giphy.gif" alt="ctrly-giphy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Rendering Tree
&lt;/h2&gt;

&lt;p&gt;Stadium staff begins to distribute each colored cardboard, and the energy of the crowd transforms from conversations to the excitement for the beginning of the game.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/J34A3KhE6XqzNTEktp/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/J34A3KhE6XqzNTEktp/giphy.gif" alt="ctrly-giphy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The process of distributing the cardboard assigned to each seat can represent the size and position of the node on the screen.&lt;/p&gt;

&lt;p&gt;The squared form of each cardboard can also represent the elements that will show on the screen.&lt;/p&gt;

&lt;p&gt;Once each node from the DOM has its style assigned, the rendering engine computes the size of each node and its position on the screen.&lt;/p&gt;

&lt;p&gt;The result of this computation is a rendering tree. Were boxes represent each of the web page’s elements.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/gFmknz76LQwimEC4oz/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/gFmknz76LQwimEC4oz/giphy.gif" alt="ctrly-giphy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;All of a sudden, the microphone turns ON, and a staff member welcomes the crowd. The game is about to begin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Paint the render tree
&lt;/h2&gt;

&lt;p&gt;The rendering engine is responsible for painting on screen the new render tree.&lt;/p&gt;

&lt;p&gt;What does painting on-screen means?&lt;/p&gt;

&lt;p&gt;Part of the computer’s memory goes to pixels. It is in the pixel memory spaces were the rendering engine sets the style value for each node. That is how pixels get their color, shape, and position.&lt;/p&gt;

&lt;p&gt;The crowd goes wild when the home team is announced. The battle chant begins. Each person from the crowd puts the cardboard over their head.&lt;/p&gt;

&lt;p&gt;The cardboard paint each stadium seat with the color, shape, and position required for the message for the team can be appreciated.&lt;/p&gt;

&lt;p&gt;“We are ready”, it reads. The energy is glorious.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NXVufTlm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/05/sport-chant.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NXVufTlm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/05/sport-chant.png" alt="'word-press image"&gt;&lt;/a&gt;&lt;/p&gt;
Credit: Scene from a Youtube video recorded by the user &lt;a href="https://www.youtube.com/channel/UCPBOvCtgSUuCjMsfOndtWHQ"&gt;barcelona.jp&lt;/a&gt;



&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;p&gt;As mentioned at the beginning of this writing, this article was inspired by &lt;a href="https://www.ladybug.dev/episodes/level-up-javascript"&gt;Ladybug’s Podcast episode: “Level Up with Javascript”&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Ladybug Podcat’s suggestions led me to a different podcast episode that inspired me with the illustrations, &lt;a href="https://www.codenewbie.org/podcast/how-do-browsers-work"&gt;The Code Newbie episode: “How Do Browsers Work?&lt;/a&gt;. The programmer and artist Lin Clark details how web browsers function, and her work at Mozilla.&lt;/p&gt;

&lt;p&gt;Also, Lin Clark wrote another article: &lt;a href="https://hacks.mozilla.org/2017/08/inside-a-super-fast-css-engine-quantum-css-aka-stylo/"&gt;“Inside a Super Fast CSS Engine: Quantum CSS (aka Stylo)”&lt;/a&gt; which details the role of CSS when rendering a page.&lt;/p&gt;

&lt;p&gt;Lin Clark’s drawings and explanations helped me understand the rendering engine. She goes more into detail of what I vaguely explained in this article so I would invite you to read those articles if you want to inquire more.&lt;/p&gt;

&lt;h2&gt;
  
  
  Side Note &lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;I wrote this article listening to the playlist &lt;a href="https://open.spotify.com/playlist/5vwbAwj4aNUsKZUSKIgy0T?si=4HSrLZUiT96YwAFfytfVxQ"&gt;“Creativity Boost”&lt;/a&gt; created by &lt;a href="https://open.spotify.com/user/1218987685"&gt;Mia Astral&lt;/a&gt; on Spotify. This playlist was recommended by a dear friend. It has a great mix of upbeat but smooth music that helped me focus.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="100%" height="380px" src="https://open.spotify.com/embed/playlist/5vwbAwj4aNUsKZUSKIgy0T%20"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>html</category>
      <category>css</category>
      <category>javascript</category>
    </item>
    <item>
      <title>A Morning in a Front End Developer’s Mac Terminal</title>
      <dc:creator>Yari Antonieta</dc:creator>
      <pubDate>Wed, 01 Apr 2020 17:12:54 +0000</pubDate>
      <link>https://forem.com/yaariii3/a-morning-in-a-front-end-developer-s-mac-terminal-4f4k</link>
      <guid>https://forem.com/yaariii3/a-morning-in-a-front-end-developer-s-mac-terminal-4f4k</guid>
      <description>&lt;p&gt;&lt;em&gt;&lt;a href="https://ctrly.blog/a-morning-in-a-front-end-developers-mac-terminal/"&gt;This story&lt;/a&gt; was originally posted on &lt;a href="https://ctrly.blog/"&gt;ctrl-y blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A &lt;a href="https://ctrly.blog/es/una-manana-en-el-terminal-mac-de-una-desarrolladora-de-front-end/"&gt;Spanish version of this article&lt;/a&gt; can be found in &lt;a href="https://ctrly.blog/es"&gt;ctrl-y blog/es&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;On the Side Note section at the end of each article, I like to share what I was listening to while writing machine or human words. I ❤️ music so I spend time (sometimes a bit too much) searching for, or creating, long playlists so I can listen to them while I'm working.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Plays Fresh Prince of Bel-Air intro song:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=t-_S3h2BVsQ"&gt;🎵Now, this is a story all about how this Front End Developer turns her terminal upside down. And I’d like to take a minute, sit right there. I’ll tell you how I use the Mac terminal throughout the day to be clear. 🎵&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/27bFNWooWXwvuFlRIT/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/27bFNWooWXwvuFlRIT/giphy.gif" alt="Fresh Prince of Bel-Air gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Slack message popped up. “Can you please check out what is causing this bug?, I am having a meeting with an important client at 3 pm today, and it would be nice to show this feature” it read.&lt;/p&gt;

&lt;p&gt;So I searched for my &lt;a href="https://open.spotify.com/playlist/1QwTIL0tj6A2iOKnAOKN8d?si=uTzKTfPzR0q9ZaHBfGhiMA"&gt; “typing furiously” playlist &lt;/a&gt;, wrapped my hair in a bun, took a sip of coffee, and hit the Spotlight Search shortcut &lt;strong&gt;[command + spacebar ]&lt;/strong&gt; to search for “Terminal” and access my Mac Operative System command line.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IwKesctE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/terminal-init.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IwKesctE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/terminal-init.png" alt="Open Terminal"&gt;&lt;/a&gt;Terminal when opened&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note: Commands will be enclosed inside square brackets ( [ ] ) .&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Let’s Command
&lt;/h2&gt;

&lt;p&gt;“Where am I?” It sounded philosophical while I thought about it, but in actuality, by typing and entering &lt;strong&gt;[ pwd ]&lt;/strong&gt; &lt;strong&gt;(Print Working Directory)&lt;/strong&gt;, I had a better idea. It is because the &lt;strong&gt;[ pwd ]&lt;/strong&gt; is like my Google Maps for file, it shows me the directory where I am.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---VRM_ERA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/pwd-terminal.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---VRM_ERA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/pwd-terminal.png" alt="Current directory"&gt;&lt;/a&gt;Current directory&lt;/p&gt;

&lt;p&gt;“Great! I am in the directory I want to be in, but I do not remember the directory I want to navigate to,” I thought about instantly.&lt;/p&gt;

&lt;p&gt;But I answered myself with: “That’s where &lt;strong&gt;[ ls ]&lt;/strong&gt; &lt;strong&gt;(List Directory Content)&lt;/strong&gt; comes in handy.” &lt;strong&gt;[ ls ]&lt;/strong&gt; shows the content inside the current directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ZPEHJXbP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/terminal-ls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ZPEHJXbP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/terminal-ls.png" alt="Inside directory"&gt;&lt;/a&gt;Content inside /Users/yari directory&lt;/p&gt;

&lt;p&gt;My thoughts continued: “Now that I remembered in which directory I cloned the project, I need to &lt;strong&gt;[ cd ]&lt;/strong&gt; &lt;strong&gt;(change directory)&lt;/strong&gt; to get to the project’s local repository.”&lt;/p&gt;

&lt;p&gt;By typing and entering &lt;strong&gt;[ cd ]&lt;/strong&gt; followed by the &lt;strong&gt;subsequent directory names&lt;/strong&gt; I want to navigate into, &lt;strong&gt;separating each directory name with a forward slash ( / )&lt;/strong&gt;, I went ahead and started to change directory.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--tXsDiI3Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-cd-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--tXsDiI3Y--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-cd-1.png" alt="Change directories"&gt;&lt;/a&gt; Change directory to src file&lt;/p&gt;

&lt;p&gt;Until I found myself inside the src (source) directory. “Wait! Is package.json inside the src file? Let me &lt;strong&gt;[ ls ]&lt;/strong&gt; this thing!” I continued.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XNLmSTwo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-ls2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XNLmSTwo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-ls2.png" alt="Inside src directory"&gt;&lt;/a&gt;Content inside the src directory&lt;/p&gt;

&lt;p&gt;“Nope, there is no way I can run the web app from this directory,” I said to myself… out loud.&lt;/p&gt;

&lt;p&gt;“Shhhhhh, I am in a meeting!” said Ramona, my coworker.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/f9RmMTtq8mlCPjuune/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/f9RmMTtq8mlCPjuune/giphy.gif" alt="Awkward sorries! gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whispering: “I need to go up a level in the directory, but how?”&lt;/p&gt;

&lt;p&gt;That’s where the dots on the command line came in handy: &lt;strong&gt;[ cd .. ]&lt;/strong&gt;. Two dots after cd means to go one level up the directory tree.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CFmVBCHQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Trerminal-cd-back.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CFmVBCHQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Trerminal-cd-back.png" alt="One level up in drectory"&gt;&lt;/a&gt;&lt;b&gt;[ cd .. ]&lt;/b&gt; goes one level up the directory tree&lt;/p&gt;

&lt;p&gt;My mind went: “Before running the app, I am going to make use of this moment to open the Visual Studio Code at this directory,” so I entered &lt;strong&gt;[ code  . ]&lt;/strong&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XQyRmOSV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-code.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XQyRmOSV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-code.png" alt="code . command"&gt;&lt;/a&gt;&lt;b&gt;[ code . ]&lt;/b&gt; command is used to open the code editor at the root directory&lt;/p&gt;

&lt;p&gt;“Ok, let’s run the app,” I thought. I entered &lt;strong&gt;[ npm start ]&lt;/strong&gt;, and off it went.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git Time!
&lt;/h2&gt;

&lt;p&gt;"Before doing anything to the code, I need to make sure that locally I have the latest version of what is in development," my thoughts continued.&lt;/p&gt;

&lt;p&gt;So it's time for the: "Git Routine."&lt;/p&gt;

&lt;p&gt;"But first ☝️, let me open a new terminal tab or window, by typing &lt;strong&gt;[ command + t ]&lt;/strong&gt;, to keep the app running on the current one," I said to myself.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/aYzxVt2lMrZXW/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/aYzxVt2lMrZXW/giphy.gif" alt="Homer pressing tab gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let me tell you, reader of my thoughts, on what my &lt;strong&gt;Almost Four Steps Git Routine&lt;/strong&gt; consists. I am assuming, though, that you know git basics. Do not worry if you do not know!  &lt;a href="https://rogerdudler.github.io/git-guide/index.html"&gt;Here is a quick intro&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Almost Four Steps Git Routine
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Check Branch Status
&lt;/h4&gt;

&lt;p&gt;First, check-in the status of the local work tree. Because frankly, I always forget what I was doing before. So, I enter the &lt;strong&gt;[ git status ]&lt;/strong&gt; command.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HFksQkMk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-status.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HFksQkMk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-status.png" alt="Branch status"&gt;&lt;/a&gt;Terminal after entering git status&lt;/p&gt;

&lt;h4&gt;
  
  
  If the branch is not clean, save changes
&lt;/h4&gt;

&lt;p&gt;Second, I have learned, after many attempts, that git will not change branch if there are code changes, and changes are not stashed (saved temporarily) or committed (merged with master branch eventually).&lt;/p&gt;

&lt;p&gt;So I proceeded to enter &lt;strong&gt;[ git stash ]&lt;/strong&gt; to save changes temporarily. &lt;/p&gt;

&lt;p&gt;Now let's see if I can change the branch from the current one to the development branch to make sure that I have the current version of the remote development branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--zxoXmIW8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-status-notClean.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--zxoXmIW8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-status-notClean.png" alt="Branch status with changes"&gt;&lt;/a&gt;Branch with changes not stashed or committed&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oaAcV6RL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-stash.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oaAcV6RL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-stash.png" alt="Stashed changes"&gt;&lt;/a&gt;&lt;b&gt;[ git stash ]&lt;/b&gt; – Changes are stashed (saved temporarily)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x3StCHg---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-status-afterStash.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x3StCHg---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-status-afterStash.png" alt="Branch status after stash"&gt;&lt;/a&gt;Checks &lt;b&gt;[ branch status ]&lt;/b&gt; to see if the working tree is clean&lt;/p&gt;

&lt;h4&gt;
  
  
  Change local branch
&lt;/h4&gt;

&lt;p&gt;Now that the branch is clean, I need to change the HEAD of the work tree to the development branch. &lt;strong&gt;[ git checkout development ]&lt;/strong&gt; does that.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aZn2UJuQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-checkout-development.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aZn2UJuQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-checkout-development.png" alt="Branch change from feature/products to development"&gt;&lt;/a&gt;&lt;b&gt;[ git checkout development ]&lt;/b&gt; switches HEAD working tree to the development branch&lt;/p&gt;

&lt;h4&gt;
  
  
  Update development branch
&lt;/h4&gt;

&lt;p&gt;Finally,  update the local development branch with the remote repository's development branch. So I enter &lt;strong&gt;[ git pull origin development ]&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fWeGJAMF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-pull-origin-development.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fWeGJAMF--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-pull-origin-development.png" alt="Update branch"&gt;&lt;/a&gt;&lt;b&gt;[ git pull origin development ]&lt;/b&gt; command updates content from remote development branch to local development branch&lt;/p&gt;

&lt;p&gt;The command &lt;strong&gt;[ git pull ]&lt;/strong&gt; fetches the development branch content on the remote repository and merges the remote branch content with local branch content. The command &lt;strong&gt;[ origin development ]&lt;/strong&gt; refers to the branch that the system will look up to make the update. &lt;em&gt;Origin&lt;/em&gt; refers to the repository of origin, in this case, the remote repository. &lt;em&gt;Development&lt;/em&gt; refers to the name of the work tree branch that the systems looks up to make updates.&lt;/p&gt;

&lt;h3&gt;
  
  
  After Routine
&lt;/h3&gt;

&lt;p&gt;From this point forwards, my git commands vary from what I need to do in the day. This time, I need to fix a bug, so I need to create a new branch and perform those changes on that new branch. That requires me to change my HEAD work tree from development to the newly created work tree branch.&lt;/p&gt;

&lt;p&gt;"What will be the name of the new branch?" started my thoughts again.&lt;/p&gt;

&lt;p&gt;"Something verbose, straight to the point," pointed out a thought with the voice of my team lead.&lt;/p&gt;

&lt;p&gt;"Let's go with &lt;em&gt;fix/this-feature&lt;/em&gt;" I decided. So I entered &lt;strong&gt;[ git checkout -b 'fix/this-feature' ]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[ git checkout ]&lt;/strong&gt; switches branches of work tree, &lt;strong&gt;[ -b ]&lt;/strong&gt; creates a new working tree branch, &lt;strong&gt;[ 'fix/this-feature' ]&lt;/strong&gt; is the new branch name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Bk7tBOt7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-checkout-fix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Bk7tBOt7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-checkout-fix.png" alt="Create new branch"&gt;&lt;/a&gt;Creates and switches to the new branch&lt;/p&gt;

&lt;p&gt;To make sure that I am not in the development branch anymore, I hit again &lt;strong&gt;[ git status ]&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wu3J4u_R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-status-fix.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wu3J4u_R--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-git-status-fix.png" alt="Create new branch"&gt;&lt;/a&gt;&lt;b&gt;[ git status ]&lt;/b&gt; to confirm that I am working on the new branch&lt;/p&gt;

&lt;p&gt;"Yeah, I am at the new branch of the work tree," I confirmed to myself. &lt;/p&gt;

&lt;p&gt;Next, I need to merge the updated branch with the new one, so the new work tree branch is up to date with the updated development branch. The command  &lt;strong&gt;[ git merge development ]&lt;/strong&gt; does that merge.&lt;/p&gt;

&lt;p&gt;Few. I am glad that I got that out of the way. These steps up until changing branches from development to the new o reworked branch always make me nervous.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/Vgldw2H2uRLRXTtWhS/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/Vgldw2H2uRLRXTtWhS/giphy.gif" alt="Relieved gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;"Now, I am ready to catch that bug!" And so, I turned to my application and code editor to search for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  An error occurred
&lt;/h3&gt;

&lt;p&gt;I was having a groove on while writing code, and everything was working fine until something happened that a confusing error started appearing.&lt;/p&gt;

&lt;p&gt;"Another application is already using the port," it read.&lt;/p&gt;

&lt;p&gt;As an excellent debugger, I stopped the program with &lt;strong&gt;[ control + c ]&lt;/strong&gt; ...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--2F0eIHwq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-control-c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2F0eIHwq--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-control-c.png" alt="Stopped program"&gt;&lt;/a&gt;Terminal after entering &lt;b&gt;[ control + c ]&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;... and reran. But it did not help.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/gdTuORN7HG0dWh2ybo/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/gdTuORN7HG0dWh2ybo/giphy.gif" alt="Dissapointed gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I asked my friend Google for some help, and it suggested to locate and kill the port process. To do this, I needed to identify the process id that I intended to kill and, well, terminate it.&lt;/p&gt;

&lt;p&gt;The command to locate and display the list of the processes happening on a port is &lt;strong&gt;[ lsof -i:PORT ]&lt;/strong&gt;, where &lt;strong&gt;[ lsof ]&lt;/strong&gt; stands for a list of open files, &lt;strong&gt;[ -i ]&lt;/strong&gt; is the list of processes and &lt;strong&gt;[ PORT ]&lt;/strong&gt; is the port number that we want to review. This case is the port 3000 so &lt;strong&gt;[ lsof -i:PORT ]&lt;/strong&gt; is really entered as &lt;strong&gt;[ lsof -i:3000 ]&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MtqUExaG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-lsof.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MtqUExaG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Terminal-lsof.png" alt="Process on port 3000"&gt;&lt;/a&gt;List of processes running in port 3000&lt;/p&gt;

&lt;p&gt;After locating the process that I wanted to terminate, I proceed to enter &lt;strong&gt;[ sudo kill -9 15010 ]&lt;/strong&gt; to kill the process. Where 15010 is the terminated processes' PID (process identification number).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_TPhJQf6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Temrinal-sudo-kill.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_TPhJQf6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/Temrinal-sudo-kill.png" alt="Terminate process"&gt;&lt;/a&gt;&lt;b&gt;[ sudo kill -9 15010 ]&lt;/b&gt; to kill the process with PID 15010 running at port 3000&lt;/p&gt;

&lt;p&gt;Ready to start rerunning the app.&lt;/p&gt;

&lt;p&gt;"Grrrrrlrllrrlrlr" growled my belly. "I am hungry, and I cannot think with my stomach screaming," I thought.&lt;/p&gt;

&lt;p&gt;"Let's go to lunch," suggested Ramona.&lt;/p&gt;

&lt;p&gt;"Please!" I responded and headed out to lunch feeling like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://i.giphy.com/media/1iNIiCaRtlT2UBc6tr/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/1iNIiCaRtlT2UBc6tr/giphy.gif" alt="Happy to go to eat gif"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Side Note&lt;a&gt;&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Enjoy a couple of &lt;strong&gt;Cheat Sheets&lt;/strong&gt; including the commands used throughout this post!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MKuXRHxh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MKuXRHxh--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/2.jpg" alt="General commands for Terminal Cheat Sheet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--BJmuH1bX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BJmuH1bX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ctrly.blog/wp-content/uploads/2020/03/1.jpg" alt="Git commands Cheat Sheet"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, I wrote this story with the newly released &lt;strong&gt;Four Tet album, Sixteen Oceans&lt;/strong&gt; playing in the background. The beginning of the first song sets an incredible mood for a subtle yet productive day. It has been my go-to album during this whole self quarantined time.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="100%" height="380px" src="https://open.spotify.com/embed/playlist/56wAIN5mE6pQ9VM8nXsAqh?si=Rz1LpMS7Qm2eq9liBtkR5Q%20"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

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

</description>
      <category>beginners</category>
      <category>git</category>
      <category>learning</category>
      <category>codenewbie</category>
    </item>
    <item>
      <title>Filtering with GraphQL and Prisma: What NOT to do</title>
      <dc:creator>Yari Antonieta</dc:creator>
      <pubDate>Tue, 24 Dec 2019 19:07:00 +0000</pubDate>
      <link>https://forem.com/yaariii3/filtering-with-graphql-and-prisma-what-not-to-do-38fk</link>
      <guid>https://forem.com/yaariii3/filtering-with-graphql-and-prisma-what-not-to-do-38fk</guid>
      <description>&lt;p&gt;&lt;em&gt;This article was originally posted on &lt;a href="https://ctrly.blog/what-not-to-do-when-filtering-with-graphql-and-prisma/" rel="noopener noreferrer"&gt;my blog: &lt;em&gt;ctrl-y&lt;/em&gt;&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A Spanish version of this article can also be found in &lt;a href="https://ctrly.blog/es/que-no-hacer-cuando-estas-filtrando-con-graphql-y-prisma/" rel="noopener noreferrer"&gt;ctrl-y&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;On the Side Note section at the end of each article, I like to share what I was listening to while writing machine or human words. I ❤️ music so I spend time (sometimes a bit too much) searching for, or creating, long playlists so I can listen to them while I'm working.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;In the past months, I have been working with the magic package of React, Apollo, GraphQL, and Prisma. I say the magic package because learning these four layers of programming, provides you with the skills required to create apps from user click (React and Apollo) to handle and save information in the database (Prisma). They say that building this makes you a Full Stack developer.&lt;/p&gt;

&lt;p&gt;I want to focus this article on GraphQL and Prisma because even thou I was already familiar with back-end languages, I only copied code. In other words, I didn’t understand how the back-end works.&lt;/p&gt;

&lt;p&gt;I reached a massive roadblock when I started working with the search function for the digital product I am helping to develop.&lt;/p&gt;

&lt;p&gt;At first, it’s easy to build functions because tutorials, even with complex topics, offer basic examples of how to create them. But what happens when basic examples are not enough?&lt;/p&gt;

&lt;p&gt;The articles I read about filtering in the database, describe examples that consider the search of the terms inside one query. Sometimes these examples included nested data.&lt;/p&gt;

&lt;p&gt;My roadblock, &lt;em&gt;what happens when I need to filter more than one query?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I want to share with you my incorrect approach when working on this task. It took me a while to figure out why this approach was wrong, and what is a better approach when searching for data in different queries.&lt;/p&gt;

&lt;h1&gt;
  
  
  How Does ReactJs, Apollo, GraphQL, and Prisma Work Together?
&lt;/h1&gt;

&lt;p&gt;Let’s make a quick recap of how ReactJs, Apollo, GraphQL, and Prisma work together.&lt;/p&gt;

&lt;h2&gt;
  
  
  ReactJs
&lt;/h2&gt;

&lt;p&gt;It is a Javascript framework (that's what the Js is for) that handles the interface functions between user and software. When we work with a feature such as a website search, the data entry function, and search submission are handled by ReactJs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apollo
&lt;/h2&gt;

&lt;p&gt;The ReactJs submit function must manually query the Apollo Client. Apollo communicates with GraphQL resolvers to request and receive information from the database using the GraphQL query language.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphQL
&lt;/h2&gt;

&lt;p&gt;It is a query language for APIs that handles the website’s data. It is where the data schemas and resolver functions are defined.&lt;/p&gt;

&lt;p&gt;GraphQL is a language. Therefore, we need to instruct which data will it filter and receive. These functions written in NodeJs (that is why usually resolver function files are Js and not Graphql) are called resolvers.&lt;/p&gt;

&lt;p&gt;It is web developer-friendly because it gives the ability to specify the data that needs to be received by the website instead of collecting everything available on the endpoint.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prisma
&lt;/h2&gt;

&lt;p&gt;It is an interface between GraphQL and the database.&lt;/p&gt;

&lt;p&gt;It is where the different queries from the database are defined and implemented.&lt;/p&gt;

&lt;p&gt;Define queries in Prisma. After a couple of commandos, Prisma autogenerates a file with the GraphQL data schema in Prisma. The data is filtered from the database using this schema.&lt;/p&gt;

&lt;h3&gt;
  
  
  In summary…
&lt;/h3&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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Frac9kzer8nbstet2q8g4.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%2Fthepracticaldev.s3.amazonaws.com%2Fi%2Frac9kzer8nbstet2q8g4.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Code Context Before Implementing the Search Function
&lt;/h1&gt;

&lt;p&gt;Let’s make some assumptions before going the wrong path for the search implementation.&lt;/p&gt;

&lt;p&gt;We are making multiple query searches on a database for a small business that handles farming equipment.&lt;/p&gt;

&lt;h2&gt;
  
  
  1) There are multiple queries available on the database
&lt;/h2&gt;

&lt;p&gt;GraphQL’s and Prisma’s schemas are defined. An example of a data schema on Prisma data model &lt;strong&gt;(prisma/datamodel.prisma)&lt;/strong&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Next, the example of the GraphQL resolver schema &lt;strong&gt;(server/src/schema.graphql)&lt;/strong&gt; with Prisma’s data schema imported:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Where the resolver &lt;em&gt;company&lt;/em&gt; requires (! = “it is required so it can’t be null”) the id argument to return data type Company.&lt;/p&gt;

&lt;p&gt;And the &lt;em&gt;users&lt;/em&gt; and &lt;em&gt;equipment&lt;/em&gt; resolvers do not require an argument to return a value. The resolver &lt;em&gt;users&lt;/em&gt; should return an array of User data types, while the &lt;em&gt;equipment&lt;/em&gt; resolver should return a data array of Equipment data types.&lt;/p&gt;

&lt;p&gt;Also, the &lt;em&gt;equipment&lt;/em&gt; resolver should return an array of no null values. Neither the data array can itself be null.&lt;/p&gt;

&lt;h2&gt;
  
  
  2) The query resolvers are defined
&lt;/h2&gt;

&lt;p&gt;So the &lt;strong&gt;sever/src/resolvers/Query.js&lt;/strong&gt; file:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;The resolver for the &lt;em&gt;company&lt;/em&gt; query must receive an id type argument. These resolvers should return the query data filtered by id.&lt;/p&gt;

&lt;p&gt;The resolvers for the &lt;em&gt;users&lt;/em&gt; and &lt;em&gt;equipment&lt;/em&gt; queries do not require an argument to return filtered data. Therefore, it will return a data array of all the records of the requested query.&lt;/p&gt;

&lt;h2&gt;
  
  
  3) Queries requested by front-end have nested data
&lt;/h2&gt;

&lt;p&gt;An example of an &lt;em&gt;equipment&lt;/em&gt; query requested by Apollo:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;An example of a &lt;em&gt;company&lt;/em&gt; query requested by Apollo:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;An example of a users query requested by Apollo:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
  Filter Data Using GraphQL and Prisma
&lt;/h1&gt;

&lt;p&gt;Remember the company query we defined earlier? An id argument filters the company query. That’s a basic example of how to filter data in GraphQL. &lt;a href="https://www.howtographql.com/react-apollo/7-filtering-searching-the-list-of-links/" rel="noopener noreferrer"&gt;It’s easy to find documentation on this topic.&lt;/a&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;An example of the resolver for the &lt;em&gt;company&lt;/em&gt; query if we want to search the id argument in each of the Company type items:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Most of the articles about filtering on GraphQL finish up to this point, where we can only filter data on a query.&lt;/p&gt;

&lt;p&gt;But, what happens if I need to search for more than one query and the data is nested?&lt;/p&gt;

&lt;h2&gt;
  
  
  My initial Erroneous Approach of Filtering Multiple Queries
&lt;/h2&gt;

&lt;p&gt;My instinct told me, after reading documentation, that I should filter queries editing the already defined resolvers (remember the previously stated examples).&lt;/p&gt;

&lt;p&gt;But, the idea of performing multiple requests to the database seemed heavy. The “edit the resolvers” approach requires that the front-end triggers a network request for every filtered query at the moment the search is submitted.&lt;/p&gt;

&lt;p&gt;I admit that the implementation of the search feature was after other elements in the app had been validated, so I inhibited myself from editing the resolvers that already worked.&lt;/p&gt;

&lt;p&gt;Also, trying to consider that code repetition is a waste, fueled my reasoning that creating a query from the queries I needed to filter was the go-to approach for handling the server.&lt;/p&gt;

&lt;p&gt;So, I defined my new query, Feed, on the Prisma data type schema &lt;strong&gt;(prisma/datamodel.prisma)&lt;/strong&gt; as:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Import the query Feed to the GraphQL resolver schema after auto-generating the Prisma file, ** (server/src/schema.graphql) ** as:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Also, the auto-generated Prisma file provides the conditions you can use as a developer to filter data on Prisma. The feed resolver &lt;strong&gt;(sever/src/resolvers/Query.js)&lt;/strong&gt; below:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Finally, the query requested from the front-end:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Some received data from the three queries as a result of these composite codes. But, the data was incomplete. I could access the nested data from the &lt;em&gt;contacts&lt;/em&gt; and &lt;em&gt;company&lt;/em&gt; inside the &lt;em&gt;equipment&lt;/em&gt;. I could only see what type of data I was receiving, but the value was null.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this is not an adequate approach?
&lt;/h2&gt;

&lt;p&gt;Looking through the documentation and frequently asked questions about this topic, the primary reason why invalid data is received when you should be able to access it is that because the data structure you are passing is incorrect.&lt;/p&gt;

&lt;p&gt;But, &lt;em&gt;what a correct schema for Feed would look like if we are already passing the right data types?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Queries have records attached to them in the database. An assigned id identifies these records. To assign these ids, one needs to create a function that allows the query to mutate (create a new id) and can save the data attached to the database record.&lt;/p&gt;

&lt;p&gt;So, you need to create a Feed &lt;em&gt;mutation&lt;/em&gt; and connect the data queries for User, Company, and Equipment. It means that you need to create and save on the database a record of type Feed every time you perform a search.&lt;/p&gt;

&lt;p&gt;Imagine how loaded would be the database if, for every search you make, you save the query combination you defined as Feed!&lt;/p&gt;

&lt;p&gt;Besides the fact that it would be too expensive and unnecessary to keep something like that, and we are not taking full advantage of the power of GraphQL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Then, what should be an appropriate approach to do searches on multiple queries?
&lt;/h2&gt;

&lt;p&gt;It’s obvious now, but to filter data queries is done in…. ta-da, the same data queries. So my instinct of adding the capacity to filter on the already defined resolvers was a better approach.&lt;/p&gt;

&lt;p&gt;When we search multiple queries on the database, the front-end requests the data query individually. Apollo handles the requests to the GraphQL resolvers, so the response is as lean as the developer needs.&lt;/p&gt;

&lt;p&gt;We do not need to define a new query to perform a search on multiple queries. So, let’s go back and re-define &lt;strong&gt;prisma/datamodel.prisma&lt;/strong&gt; as:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Also, let’s go back and edit the GraphQL resolver schema &lt;strong&gt;(server/src/schema.graphql)&lt;/strong&gt;. Delete the Feed type definition and add the filter parameter to each query. The filter parameter is the data string the user wrote as the input for the search function:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Note: I assigned filter as an optional parameter so I can use these resolvers on other components.&lt;/p&gt;

&lt;p&gt;On the GraphQL resolvers &lt;strong&gt;(sever/src/resolvers/Query.js)&lt;/strong&gt;, where the magic happens, we eliminate the feed resolver and edit the other resolvers, so each data query accepts the filter argument:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And the data queries that front-end requests:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This approach to filtering multiple queries should result in receiving all the data requested, including the nested data.&lt;/p&gt;

&lt;p&gt;Ufff, we finished!&lt;/p&gt;

&lt;p&gt;Thanks for reading all of this! 🙌🎉&lt;/p&gt;

&lt;p&gt;It took me a while to come to this conclusion. If I can help you save a couple of hours or days by reading this article, that would be a &lt;em&gt;mega&lt;/em&gt; mission accomplished!&lt;/p&gt;

&lt;h1&gt;
  
  
  Side Note
&lt;/h1&gt;

&lt;p&gt;I wrote this article while listening to the &lt;a href="https://ladybug.dev/" rel="noopener noreferrer"&gt;Ladybug Podcast&lt;/a&gt;. It is rare for me to listen to a podcast while writing, but the topics the girls talked about motivated me to write this article.&lt;/p&gt;

&lt;p&gt;Ladybug Podcast is a program focused on web development topics. Hosted by &lt;a href="https://dev.to/kelly"&gt;Kelly Vaughn&lt;/a&gt;, &lt;a href="https://dev.to/aspittel"&gt;Ali Spittel&lt;/a&gt;, and &lt;a href="https://dev.to/emmawedekind"&gt;Emma Wedekind&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even thou I binge listened to the podcast, I am sharing the episode that is about GraphQL, which I also listened to while writing this article.&lt;/p&gt;

&lt;p&gt;&lt;iframe src="https://open.spotify.com/embed/episode/0GcIvkAyFVovTQX00i3eO3" width="100%" height="232px"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>graphql</category>
      <category>webdev</category>
      <category>react</category>
    </item>
    <item>
      <title>Web Dev Cheat Sheets</title>
      <dc:creator>Yari Antonieta</dc:creator>
      <pubDate>Fri, 08 Nov 2019 15:57:27 +0000</pubDate>
      <link>https://forem.com/yaariii3/web-development-cheat-sheets-2k7l</link>
      <guid>https://forem.com/yaariii3/web-development-cheat-sheets-2k7l</guid>
      <description>&lt;p&gt;Hi Devs!👋 Can you recommend a tool/app for web development cheat sheets?  I would like to have cheat sheets stored in one place, so I don't have to waste time searching, bookmarking or saving them.&lt;/p&gt;

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

</description>
      <category>discuss</category>
    </item>
    <item>
      <title>Industrial Engineering and Web Development</title>
      <dc:creator>Yari Antonieta</dc:creator>
      <pubDate>Sat, 02 Nov 2019 20:41:51 +0000</pubDate>
      <link>https://forem.com/yaariii3/industrial-engineering-and-web-development-43b2</link>
      <guid>https://forem.com/yaariii3/industrial-engineering-and-web-development-43b2</guid>
      <description>&lt;p&gt;&lt;i&gt;Originally posted on &lt;a href="https://ctrly.blog"&gt;ctrl-y blog&lt;/a&gt;, April 07, 2019.&lt;/i&gt;&lt;/p&gt;

&lt;h3&gt;Mental Change: From Industrial Engineering to Web Development&lt;/h3&gt;

&lt;p&gt;A frequent question I get asked when I talk about my career change from industrial engineering to web development is: “Is your Industrial Engineering knowledge useful for Web Development?”&lt;/p&gt;

&lt;p&gt;I also asked myself that question before leaping and switched careers. But the more I learn about programming web-based products, the more I can relate Industrial Engineering with the development of digital products.&lt;/p&gt;

&lt;p&gt;It wasn’t until I took a UI/UX Design workshop, that I realized that the UI/UX concepts came from human-centered manufacturing concepts.&lt;/p&gt;

&lt;p&gt;So, how do I relate Web Development to Industrial Engineering?&lt;/p&gt;

&lt;h3&gt;Problem Solving&lt;/h3&gt;

&lt;p&gt;For starters, both professions require the capacity to solve problems. Ok, let me rephrase that. Both require the ability to visualize the problem and solve it. Some people are born with that talent. Others require a bachelor's degree to develop it (here, present  🙋‍♀️). But definitely, you need to train your brain into creating a mental map of the problem, for you to develop a mental map of solutions.&lt;/p&gt;

&lt;h3&gt;Ability to detail step procedures&lt;/h3&gt;

&lt;p&gt;In the regulated manufacturing world, it is required to document the processes that are performed to deliver a product to its final specifications. These documents may require a lot of detailed instructions, something that trains a person to think and write instructions step by step.&lt;/p&gt;

&lt;p&gt;On the other hand, writing programs for web-based products is about detailing step by step the actions that you want the computer to do. The software should be written in a straightforward manner and efficient frameworks so that the software execution runs smoothly.&lt;/p&gt;

&lt;h3&gt;Design for Users&lt;/h3&gt;

&lt;p&gt;An industrial engineers’ work is to design a process so that the operator, or performer of that process, can execute their tasks seamlessly.&lt;/p&gt;

&lt;p&gt;From the web development perspective, UX/UI design is about designing the digital product, so that the user does not have to work when using the product. Both professionals seek to minimize the user’s work.&lt;/p&gt;

&lt;h3&gt;Lean manufacturing, my soul-friend&lt;/h3&gt;

&lt;p&gt;Does Toyota sound familiar? One of their directors after the Second World War, &lt;a href="https://es.wikipedia.org/wiki/Taiichi_Ohno"&gt;Taiichi Ohno&lt;/a&gt;, created the lean manufacturing principles. The principles seek to eliminate waste, or &lt;i&gt;Muda&lt;/i&gt;, that do not aggregate value to the final product. The seven (7) wastes are:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Overproduction&lt;/li&gt;
  &lt;li&gt;Wait time&lt;/li&gt;
  &lt;li&gt;Transportation&lt;/li&gt;
  &lt;li&gt;Movement&lt;/li&gt;
  &lt;li&gt;Over-processing&lt;/li&gt;
  &lt;li&gt;Defects&lt;/li&gt;
  &lt;li&gt;Inventory&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I will not go into detail on the definition of each of the previously mentioned wastes, but &lt;a href="https://www.lean.org/lexicon/seven-wastes"&gt;here&lt;/a&gt; is a link that provides that information.&lt;/p&gt;

&lt;p&gt;Even thou waste as a concept was developed based on manufacturing processes, its easy to apply them for the development of digital products.&lt;/p&gt;

&lt;p&gt;The following table demonstrates a few examples of waste produced in manufacturing and web development.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
         &lt;tr&gt;
            &lt;th&gt;Waste&lt;/th&gt;
            &lt;th&gt;Manufacturing&lt;/th&gt;
            &lt;th&gt;Web Development&lt;/th&gt;
         &lt;/tr&gt;
         
         &lt;tr&gt;
            &lt;td&gt;Overporduction&lt;/td&gt;
            &lt;td&gt;
                1) Make the product before the client orders it.
                &lt;br&gt;
                2) To continue an operation when it should have been 
                stopped.
            &lt;/td&gt;
            &lt;td&gt;
                1) Create functions that the client did not require.
                &lt;br&gt;
                2) Create variables that do not save the necessary data. 
                &lt;br&gt;
                3) Make unnecessary continuous requests to the server. 
             &lt;/td&gt;
         &lt;/tr&gt;
         &lt;tr&gt;
            &lt;td&gt;Wait time&lt;/td&gt;
            &lt;td&gt; 
                1) Product waiting to be processed because of the 
                equipment is being maintained.
            &lt;/td&gt;
            &lt;td&gt;
                1) The time the server takes to send and receive 
                requests.
                &lt;br&gt;
                2) Wait time until data can be presented to the user. 
            &lt;/td&gt;
         &lt;/tr&gt;
         &lt;tr&gt;
             &lt;td&gt;Transportation&lt;/td&gt;
             &lt;td&gt;
                1) Unnecessarily move product from a work station to 
                another.
             &lt;/td&gt;
             &lt;td&gt;
                1) Migrate software from one platform to another because of idesign errors.
             &lt;/td&gt;
         &lt;/tr&gt;
         &lt;tr&gt;
             &lt;td&gt;Movement&lt;/td&gt;
             &lt;td&gt;
                1) Scrap a product because of a sudden stop of the 
                   equipment causes damage to the product.
             &lt;/td&gt;
             &lt;td&gt;
                1) Change files that contain variables, components, or 
                   views from their respective directives.
             &lt;/td&gt;
         &lt;/tr&gt;
         &lt;tr&gt;
             &lt;td&gt;Over-processing&lt;/td&gt;
             &lt;td&gt;
                1) Rework the same part multiple times to reach the 
                   required dimensions.
             &lt;/td&gt;
             &lt;td&gt;
                1) Rework code lines because methods used covered a use 
                   case but produced bugs on another.
             &lt;/td&gt;
         &lt;/tr&gt;
         &lt;tr&gt;
             &lt;td&gt;Defects&lt;/td&gt;
             &lt;td&gt;
                1) Assembly error causes that a part of a product does 
                not function appropriately.
             &lt;/td&gt;
             &lt;td&gt;
                1) BUGS! The software does not function correctly.
             &lt;/td&gt;
         &lt;/tr&gt;
         &lt;tr&gt;
             &lt;td&gt;Inventory&lt;/td&gt;
             &lt;td&gt;
                1) Save too much raw material in a warehouse.
             &lt;/td&gt;
             &lt;td&gt;
                1) Create variables, and functions, just in case, a programmer needs them.
             &lt;/td&gt;
         &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;Physical and digital product development&lt;/h3&gt;

&lt;p&gt;It has been exciting to experiment and participate in the process of the development of physical and digital products.&lt;/p&gt;

&lt;p&gt;Now, knowing that developing a product on the web is literally in my hands gives me a confidence in myself that was unprecedented.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>career</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
