<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Nnamani Ezinne Martina on Medium]]></title>
        <description><![CDATA[Stories by Nnamani Ezinne Martina on Medium]]></description>
        <link>https://medium.com/@nnamani.ezinne?source=rss-236b66258bcb------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*ZLsy9UmdQQWxJoYIWd9OUw.jpeg</url>
            <title>Stories by Nnamani Ezinne Martina on Medium</title>
            <link>https://medium.com/@nnamani.ezinne?source=rss-236b66258bcb------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 06:56:59 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@nnamani.ezinne/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[From Raw Data to Insights: My Airbnb Listings Analysis Using Tableau]]></title>
            <link>https://medium.com/@nnamani.ezinne/from-raw-data-to-insights-my-airbnb-listings-analysis-using-tableau-7a54fb5bd224?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/7a54fb5bd224</guid>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Tue, 18 Aug 2026 21:01:15 GMT</pubDate>
            <atom:updated>2026-08-18T21:01:15.009Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XT_ZFSO5cKj_vaYTBuPnpg.png" /></figure><p><strong>Introduction</strong><br>As part of my data analytics learning journey, I completed an exploratory data analysis project using Tableau. For this project, I worked with Airbnb listing data and built an interactive dashboard to explore how location, property size, pricing, and time relate to Airbnb listings.</p><p>The goal was not simply to create charts. I wanted to turn a large dataset into visuals that could answer practical questions about pricing and listing distribution.</p><p><strong>Project Objective</strong><br>The project explored questions such as:<br>- How does the average listing price vary by number of bedrooms?<br>- Which zipcodes have higher average listing prices?<br>- How are listings distributed across bedroom categories?<br>- How does the total calendar price change over time?</p><p><strong>Dataset</strong><br>The workbook contains three related datasets:<br>- Listings: 3,818 records and 92 fields describing Airbnb properties, hosts, prices, bedrooms, locations, reviews, and availability.<br>- Reviews: 84,849 review records.<br>- Calendar: daily availability and price records used for time-based analysis.</p><p><strong>Tools Used</strong><br>- Tableau<br>- Microsoft Excel<br>- Tableau Cloud</p><p><strong>Data Preparation and Exploration</strong><br>I first explored the available fields and identified variables that were useful for answering the business questions. These included price, zipcode, bedrooms, listing ID, date, and calendar price.</p><p>I then created separate worksheets before combining them into a dashboard.</p><p><strong>Analysis and Visualizations</strong></p><p><strong>1. Average Price by Number of Bedrooms</strong><br>The first visualization compares average listing price across bedroom categories. Property size is an important factor when analysing Airbnb pricing, and this chart makes the relationship easier to understand.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cAbCmHGi2FNfYklEfniAYQ.png" /></figure><p><strong>2. Number of Listings by Bedrooms</strong><br>Next, I analysed the distribution of listings by bedroom count. This helps show which property sizes are most common in the dataset.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5a9dFrzL19PSlR6kNZps-w.png" /></figure><p><strong>3. Average Price by Zipcode</strong><br>Location can strongly influence accommodation prices. I compared average prices across zipcodes to identify areas with relatively higher-priced listings.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XT_ZFSO5cKj_vaYTBuPnpg.png" /></figure><p><strong>4. Calendar Price Over Time<br></strong>Finally, I used the calendar data to create a time-based view of total listed prices.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qgfzl8ILnF19SNku4VAv6w.png" /></figure><p><strong>Key Insights</strong><br>From the analysis, several patterns became clear:<br>- Pricing varies across different property sizes.<br>- The number of bedrooms provides useful context when comparing listings.<br>- Location matters: average prices differ significantly across zipcodes.<br>- The dataset contains far more listings in some bedroom categories than others.<br>- Time-based data can reveal how the overall value of listed inventory changes across the available period.</p><p>The listings dataset contained 3,818 properties. The overall average listed price was approximately $128, while the median price was $100. The difference between the average and median also suggests that higher-priced properties influence the overall average.</p><p><strong>Dashboard</strong><br>After creating the individual worksheets, I combined them into a Tableau dashboard so that the insights could be viewed together. The dashboard brings pricing, location, property size, listing distribution, and time-based information into one analytical view.</p><p><strong>What I Learned</strong><br>This project helped me practice several important data analytics skills:<br>- Understanding a new dataset<br>- Selecting useful variables for analysis<br>- Creating clear visualizations in Tableau<br>- Comparing categorical and numerical data<br>- Analysing geographic and time-based patterns<br>- Communicating findings through a dashboard</p><p><strong>Challenges</strong><br>One challenge was working with a large workbook containing multiple related tables and many fields. Rather than trying to analyse everything, I focused on variables that directly supported the questions I wanted to answer.</p><p>Another challenge was choosing visualizations that communicated the findings clearly. This reinforced an important lesson: a good dashboard is not about using as many charts as possible. It is about selecting visuals that help answer specific questions.</p><p><strong>Conclusion</strong><br>This Airbnb Listings project was another important step in my data analytics journey. It gave me hands-on experience working with real-world data and using Tableau to transform raw records into meaningful insights.</p><p>I am continuing to build my portfolio through practical projects using Excel, SQL, Tableau, and other data analytics tools.</p><p>If you are also learning data analytics, I would love to connect and learn together.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7a54fb5bd224" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My First Excel Data Analysis Project: From Raw Data to an Interactive Dashboard]]></title>
            <link>https://medium.com/@nnamani.ezinne/my-first-excel-data-analysis-project-from-raw-data-to-an-interactive-dashboard-d905e9f48349?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/d905e9f48349</guid>
            <category><![CDATA[data-visualization]]></category>
            <category><![CDATA[data-analysis]]></category>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Sat, 08 Aug 2026 13:29:58 GMT</pubDate>
            <atom:updated>2026-08-08T13:29:58.158Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lSsCvy2-sPT9Pcl5louHmg.png" /></figure><p>When I decided to start my journey into Data Analytics, I knew I needed more than watching tutorials. I needed to build projects.</p><p>So instead of just learning Excel formulas, I challenged myself to complete a small data analysis project from start to finish.</p><p>For this project, I worked with a dataset containing information about <strong>1,000 customers</strong> and their bike purchasing behavior.</p><p>My goal was to use Excel to clean the data, explore it, identify patterns, and turn those findings into an interactive dashboard.</p><p>This gave me the opportunity to experience what a real data analysis workflow looks like.</p><h3>Step 1: Understanding the Dataset</h3><p>Before doing any analysis, I wanted to understand what I was working with.</p><p>The dataset contained customer information such as:</p><ul><li>Marital Status</li><li>Gender</li><li>Income</li><li>Number of Children</li><li>Education</li><li>Occupation</li><li>Home Ownership</li><li>Number of Cars</li><li>Commute Distance</li><li>Region</li><li>Age</li><li>Bike Purchase Status</li></ul><p>At first, it was simply a spreadsheet containing rows and rows of customer information.</p><p>But I quickly realized that the data could answer interesting questions about customer behavior.</p><p>Before jumping into charts, however, I needed to clean the data.</p><h3>Step 2: Cleaning the Data</h3><p>Raw data is rarely ready for analysis.</p><p>Some of the values in the dataset were abbreviated, which made them less readable.</p><p>For example:</p><ul><li>M became <strong>Married</strong> or <strong>Male</strong>, depending on the column</li><li>S became <strong>Single</strong></li><li>F became <strong>Female</strong></li></ul><p>I also created a new feature called <strong>Age Bracket</strong> using nested IF functions.</p><p>Instead of analyzing hundreds of individual ages, I grouped customers into three categories:</p><ul><li><strong>Adolescence:</strong> Less than 31</li><li><strong>Middle Age:</strong> 31–54</li><li><strong>Old:</strong> 55+</li></ul><p>This simple transformation made the data much easier to analyze.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f6mB3f69DhuniIn77sYnPQ.png" /></figure><p>It also taught me one of my first important lessons in data analytics:</p><blockquote><strong><em>Good analysis often starts with good data preparation.</em></strong></blockquote><p>If the data isn’t clean and structured properly, the analysis that follows can easily become confusing or misleading.</p><h3>Step 3: Exploring the Data with Pivot Tables</h3><p>After cleaning the dataset, I started using Pivot Tables to answer some business questions.</p><p>I focused on three main areas:</p><h3>1. Does income influence bike purchases?</h3><p>I compared the average income of customers based on gender and whether they purchased a bike.</p><p>One interesting observation was that customers who purchased bikes generally had a higher average income than those who did not.</p><p>For the overall dataset:</p><ul><li>Customers who did not purchase a bike had an average income of approximately <strong>$54,875</strong></li><li>Customers who purchased a bike had an average income of approximately <strong>$57,963</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IzA-A8qcpcYbUSJUxUTVAg.png" /></figure><p>This showed me a noticeable relationship between income and bike purchasing behavior in the dataset.</p><p>However, I also learned something important about interpreting data:</p><p>A relationship does not necessarily mean that one factor causes another.</p><p>So rather than saying that higher income <em>causes</em> customers to buy bikes, I would describe it as an <strong>association observed in this dataset</strong>.</p><h3>2. Does commute distance affect purchasing decisions?</h3><p>Next, I analyzed bike purchases based on commute distance.</p><p>This was particularly interesting.</p><p>Customers with shorter commute distances appeared more likely to purchase bikes.</p><p>For example, customers commuting <strong>0–1 miles</strong> had:</p><ul><li>200 bike purchases</li><li>166 non-purchases</li></ul><p>That’s approximately a <strong>55% purchase rate</strong>.</p><p>Customers commuting <strong>more than 10 miles</strong>, on the other hand, had:</p><ul><li>33 bike purchases</li><li>78 non-purchases</li></ul><p>That’s approximately a <strong>30% purchase rate</strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EQ9Qm4VOxW9nnXRboZWK2w.png" /></figure><p>The pattern made me think about how commuting distance and transportation choices might be connected.</p><p>Again, this doesn’t prove that commute distance causes someone to purchase or not purchase a bike, but it is an interesting pattern worth exploring further.</p><h3>3. Which age group buys the most bikes?</h3><p>The Age Bracket column I created earlier became particularly useful here.</p><p>The dataset contained:</p><ul><li><strong>110</strong> customers in the Adolescence group</li><li><strong>701</strong> customers in the Middle Age group</li><li><strong>189</strong> customers in the Old group</li></ul><p>The Middle Age group stood out.</p><p>Out of 701 customers between the ages of 31 and 54:</p><p><strong>383 purchased a bike.</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*f6mB3f69DhuniIn77sYnPQ.png" /></figure><p>That means approximately <strong>55%</strong> of customers in this group purchased a bike.</p><p>Compared with:</p><ul><li>Adolescence: approximately <strong>35%</strong></li><li>Middle Age: approximately <strong>55%</strong></li><li>Old: approximately <strong>31%</strong></li></ul><p>This was one of my favorite findings from the project.</p><p>It showed me how a simple transformation of the data can make a pattern much easier to identify and communicate.</p><h3>Step 4: Building the Dashboard</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DVB9b7O9eOtf2zo7MGYV5w.png" /></figure><p>Once I completed the Pivot Tables, I wanted to bring everything together.</p><p>So I created an Excel dashboard to present the results visually.</p><p>Instead of scrolling through hundreds of rows or looking at separate tables, the dashboard provided a more convenient way to explore the findings.</p><p>This was probably my favorite part of the project.</p><p>It was the moment I could see the entire process coming together:</p><p><strong>Raw Data → Cleaned Data → Analysis → Visualization → Insights</strong></p><p>It also helped me understand that data analysis isn’t only about finding numbers.</p><p>It’s also about presenting those numbers in a way that makes sense to other people.</p><h3>What I Learned</h3><p>This project taught me much more than Excel formulas.</p><p>I learned a simple but powerful data analysis workflow:</p><ol><li><strong>Understand the data</strong></li><li><strong>Clean the data</strong></li><li><strong>Create meaningful features</strong></li><li><strong>Analyze the data</strong></li><li><strong>Communicate the insights</strong></li></ol><p>I also learned that asking the right questions is just as important as knowing the right Excel functions.</p><p>A Pivot Table is useful, but it becomes much more useful when you know <strong>what question you’re trying to answer with it</strong>.</p><h3>My Biggest Takeaway</h3><p>Before starting this project, I thought learning Excel for Data Analytics would mostly involve learning formulas and functions.</p><p>Now I see it differently.</p><p>Excel is a tool.</p><p>The real skill is learning how to use that tool to investigate questions, identify patterns, and communicate findings.</p><p>This project started with a spreadsheet full of raw customer data.</p><p>I cleaned it.</p><p>I transformed it.</p><p>I explored it.</p><p>I found patterns.</p><p>And finally, I built a dashboard to communicate what I found.</p><p>That experience made me realize that I wasn’t simply learning Excel anymore.</p><p><strong>I was learning how to think like a data analyst.</strong></p><h3>What’s Next?</h3><p>Excel is only the beginning of my Data Analytics journey.</p><p>I’m continuing to learn:</p><ul><li>Power BI</li><li>Python</li><li>Statistics</li><li>Data Visualization</li></ul><p>My goal is to keep building projects that strengthen my analytical thinking and help me solve real-world business problems.</p><p>I’m also documenting my journey publicly through GitHub and Medium.</p><p>Each project is another opportunity to learn something new.</p><h3>Final Thoughts</h3><p>If you’re also starting your journey into Data Analytics, here’s something I’m learning along the way:</p><p><strong>Don’t wait until you feel ready before building projects.</strong></p><p>Take a dataset.</p><p>Ask questions.</p><p>Try to answer them.</p><p>Make mistakes.</p><p>Clean the data.</p><p>Build something.</p><p>Then document what you learned.</p><p>You don’t need to know everything before you start.</p><p>You just need to start.</p><p>This is my first Excel data analysis project, and I’m excited to see where the next project takes me.</p><p><strong>One dataset at a time.</strong></p><p>If you’re also learning Data Analytics, I’d love to connect and learn alongside you.</p><p>Happy learning!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d905e9f48349" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[My First Real SQL Project: Cleaning a Messy Layoffs Dataset]]></title>
            <link>https://medium.com/@nnamani.ezinne/my-first-real-sql-project-cleaning-a-messy-layoffs-dataset-d338aa844c45?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/d338aa844c45</guid>
            <category><![CDATA[data-analysis]]></category>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Wed, 05 Aug 2026 21:36:31 GMT</pubDate>
            <atom:updated>2026-08-05T21:43:07.102Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*03uIfBBw5sebyI9sF9a7kA.png" /></figure><p>A few weeks ago, I started building toward something new. I picked data analysis, and I picked SQL as my starting point.</p><p>This is a walkthrough of my first real project, cleaning a dataset of global tech layoffs, built while following Alex The Analyst’s Data Analyst bootcamp series on YouTube. It’s not a complex project. But it taught me more about how real data behaves than any amount of reading tutorials passively ever could.</p><h3>Why start with data cleaning?</h3><p>It’s tempting, when you’re new, to want to jump straight to the “exciting” part like dashboards, charts, insights. But almost every data analyst will tell you the same thing: the unglamorous work of cleaning data is where most of the actual time goes, and where most of the actual skill shows up. A chart built on a messy table is just a good-looking wrong answer.</p><p>So I decided to sit with the boring part first.</p><h3>The dataset</h3><p>The dataset tracked layoffs at tech companies, company name, location, industry, number of people laid off, percentage of the workforce affected, date, funding stage, country, and funds raised. On the surface, it looked usable. It was not.</p><p>Here’s what I found once I actually looked closely:</p><ul><li><strong>Duplicate rows: </strong>This can be in the form of the same layoff event recorded more than once.</li><li><strong>Inconsistent category labels — </strong>several different spellings/variants of “Crypto” as an industry</li><li><strong>A stray character</strong> — “United States” and “United States.” (yes, with a trailing period) treated as two different countries</li><li><strong>Dates stored as text</strong>, not as actual date values</li><li><strong>Blank and NULL values</strong> scattered across several columns, some of which were recoverable, some of which weren’t</li></ul><p>None of these is exotic problems. They’re the kind of thing you’ll hit in almost any real dataset, which is exactly why this was a good place to start.</p><h3>Step 1: Never touch the raw data</h3><p>Before writing a single cleaning query, I made a staging copy of the table:</p><pre>CREATE TABLE layoffs_staging<br>LIKE layoffs;</pre><pre>INSERT layoffs_staging<br>SELECT * FROM layoffs;</pre><p>This felt like an obvious step once I understood why it mattered: if a cleaning step goes wrong, you want to be able to start over from the original data, not from an already-damaged copy of it.</p><h3>Step 2: Finding duplicates with ROW_NUMBER()</h3><p>SQL doesn’t have a simple “highlight the duplicates” button. Instead, I used a window function, ROW_NUMBER(), partitioned across every column:</p><pre>SELECT *,<br>    ROW_NUMBER() OVER (<br>        PARTITION BY company, location, industry, total_laid_off,<br>                      percentage_laid_off, `date`, stage, country,<br>                      funds_raised_millions<br>    ) AS row_num<br>FROM layoffs_staging;</pre><p>Any row where row_num came back as 2 or higher meant it was an exact repeat of a row that appeared earlier. I wrapped this in a CTE to isolate just the duplicates, spot-checked a few (Casper, a mattress company, was a good example), confirmed they were genuine repeats, and deleted them.</p><p>This was the first moment the project clicked for me understanding that ROW_NUMBER() isn&#39;t just a way to number rows, it&#39;s a way to <em>detect</em> something.</p><h3>Step 3: Standardizing messy text</h3><p>A few examples of what “standardizing” actually meant in practice:</p><ul><li>Trimming stray whitespace from company names with TRIM()</li><li>Collapsing multiple “Crypto” variants into a single consistent label</li><li>Catching that “United States” had a hidden trailing period on some rows, using TRIM(TRAILING &#39;.&#39; FROM country)</li><li>Converting the date column from text into an actual DATE type with STR_TO_DATE(), so it could eventually be sorted and filtered properly</li></ul><p>None of this is difficult SQL. What it required was <em>noticing</em> running SELECT DISTINCT on every column and actually reading the output, rather than assuming the data was clean because it looked clean at a glance.</p><h3>Step 4: Backfilling what could be recovered</h3><p>Some rows were missing an industry value, but the same company appeared elsewhere in the dataset <em>with</em> an industry filled in. Rather than deleting or guessing, I recovered it with a self-join:</p><pre>UPDATE layoffs_staging2 t1<br>JOIN layoffs_staging2 t2<br>    ON t1.company = t2.company<br>    AND t1.location = t2.location<br>SET t1.industry = t2.industry<br>WHERE t1.industry IS NULL<br>AND t2.industry IS NOT NULL;</pre><p>I matched on company <em>and</em> location, not just company, since a company could plausibly operate in different industries across different branches or offices. Getting this join condition right mattered more than I expected going in, it was the step I revisited and corrected after a first pass.</p><p>Rows that had no usable data at all, no total laid off, no percentage laid off, I removed. There was nothing left to analyze in them.</p><h3>What I’d do differently next time</h3><ul><li>I’d validate the date format across the <em>entire</em> dataset before applying STR_TO_DATE(), rather than assuming a sample was representative. That function fails silently on formats it doesn&#39;t expect.</li><li>I’d write my join conditions more carefully the first time. I caught the location-matching issue on this project, but it’s the kind of thing that’s easy to miss.</li></ul><h3>Why this mattered to me</h3><p>This wasn’t a complicated project. But it was the first time I’d taken raw, real, flawed data and made a series of deliberate, defensible decisions about how to fix it, rather than just following a tutorial by rote. Every step needed a “why,” and being able to explain that why is, I think, the actual skill being built here.</p><p>The full project, including the cleaning script and both the raw and cleaned datasets, is on my <a href="https://github.com/Ezinnem/sql-layoffs-data-cleaning">GitHub</a></p><p>Next up: exploratory analysis of the same cleaned dataset, looking for trends by industry, company stage, and time.</p><p><em>If you’re also making a career pivot into data analysis, I’d love to hear how you’re approaching it — feel free to connect.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d338aa844c45" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building My First Cypress Test Suite for an Absolute Beginner]]></title>
            <link>https://medium.com/@nnamani.ezinne/building-my-first-cypress-test-suite-for-an-absolute-beginner-6fd795116710?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/6fd795116710</guid>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Thu, 14 Aug 2025 14:45:50 GMT</pubDate>
            <atom:updated>2025-08-14T14:45:50.222Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*oT2UgXrfuoUdC6lkRVAV9Q.gif" /></figure><h4><strong>Introduction: Why Automate Form Testing?</strong></h4><p>Forms are one of the most common features on the web — whether you’re signing up for a service, placing an order, or submitting feedback. But here’s the challenge: how do we make sure these forms work exactly as intended, every single time?</p><p>That’s where <strong>Cypress</strong> comes in. It’s a powerful testing tool that lets you simulate real user interactions in a browser, so you can be confident your forms are working perfectly.</p><p>In this beginner-friendly tutorial, you’ll:</p><ul><li><strong>Build</strong> a simple React form with fields for <strong>Name</strong>, <strong>Address</strong>, <strong>Age</strong>, and <strong>Continent</strong>.</li><li><strong>Style</strong> it to look clean and user-friendly.</li><li><strong>Install Cypress</strong> and write your first end-to-end test.</li><li><strong>Understand each Cypress command</strong> so you know exactly what’s happening at every step.</li></ul><p>By the end, you’ll have a fully functional form and an automated test that verifies it works — even if you’ve never touched Cypress before.</p><p><strong>Tools and Technologies Used</strong></p><ul><li><strong>Cypress</strong> — for end-to-end testing with real browser interactions.</li><li><strong>React.js</strong> — to build our form and handle state.</li></ul><h4>Step-by-Step Guide to Building the Full Form Test</h4><h4>Step 1 — Set Up the Project</h4><p>First, let’s create a new React app.<br><strong>Open your terminal</strong> and run:</p><pre>npx create-react-app my-form-project<br>cd my-form-project<br>npm start</pre><p>If everything works, you should see the default React page at<br> <a href="http://localhost:3000/">http://localhost:3000</a>.</p><h4>Step 2 — Folder Structure</h4><p>Before adding anything, here’s the basic folder structure we’ll end up with:</p><pre>my-form-project/<br>├── cypress/<br>│   ├── e2e/<br>│   │   └── form.cy.js       # Cypress test file<br>│   ├── fixtures/<br>│   ├── support/<br>├── src/<br>│   ├── components/<br>│   │   └── Form.js          # Our form<br>│   │   └── Form.css         # Form styles<br>│   ├── App.js<br>│   ├── index.js<br>└── package.json</pre><p>This makes it easier to stay organised.</p><h4>Step 3 — Create the Form Component</h4><p>Inside src/components/Form.js:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/768e8473e3f4618f2e7cb308ab81b6ca/href">https://medium.com/media/768e8473e3f4618f2e7cb308ab81b6ca/href</a></iframe><h4>Step 4 — Add Styling</h4><p>Inside src/components/Form.css:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5fa80f31ca49c98ef1de53f3803b8665/href">https://medium.com/media/5fa80f31ca49c98ef1de53f3803b8665/href</a></iframe><h4>Step 5 — Display the Form in App.js</h4><p>Open src/App.js:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/20a8e5f1e4813a839f9632e92c1a2cda/href">https://medium.com/media/20a8e5f1e4813a839f9632e92c1a2cda/href</a></iframe><p>Let us view the React app in the browser<br>Open the terminal and Run:</p><pre>npm start</pre><p>View in the browser:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Q4srI_HJals7Y0g7CHxo1A.png" /><figcaption>Image of the form</figcaption></figure><h4>Step 6 — Install Cypress</h4><p>In your project folder, run:</p><pre>npm install --save-dev cypress</pre><p>Then open Cypress for the first time:</p><pre>npx cypress open</pre><p>This opens a Cypress window and creates a new cypress/ folder automatically.</p><p>Select the E2E testing option and create cypress/e2e/form.cy.js file.</p><p>This may run the default test template. We can edit the form.cy.js file in our code editor.</p><h4>Step 7 — Write the Cypress Test</h4><p>Inside cypress/e2e/form.cy.js Edit the template test and write this:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/f79f6f620caa2dc0fd9bdb824e915094/href">https://medium.com/media/f79f6f620caa2dc0fd9bdb824e915094/href</a></iframe><ul><li><strong>cy.visit(url)</strong> – Opens your app in Cypress.</li><li><strong>cy.get(selector)</strong> – Selects an element on the page.</li><li><strong>.type(text)</strong> – Types text into an input field.</li><li><strong>.select(option)</strong> – Selects a dropdown option.</li><li><strong>.click()</strong> – Clicks a button or link.</li><li><strong>.on(&#39;window:alert&#39;)</strong> – Listens for alert pop-ups.</li></ul><h4>Step 8 — Run the Test</h4><p>To run interactively (with a visual Cypress browser):</p><pre>npx cypress open</pre><p>To run in the terminal (headless mode):</p><pre>npx cypress run</pre><p>Now the Cypress window opened in the browser should look like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/400/1*oT2UgXrfuoUdC6lkRVAV9Q.gif" /></figure><h4>Step 9 — Conclusion</h4><p>Congratulations! You just:</p><ul><li>Built a simple React form</li><li>Styled it with CSS</li><li>Installed Cypress and wrote your <strong>first automated test</strong></li><li>Learned the meaning of key Cypress commands</li></ul><p>From here, you can:</p><ul><li>Add more fields and validations</li><li>Test for invalid input</li><li>Test error messages and form resets</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6fd795116710" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Understanding API, Endpoint, Gateway, and Load Balancer]]></title>
            <link>https://medium.com/@nnamani.ezinne/understanding-api-endpoint-gateway-and-load-balancer-e16322f38113?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/e16322f38113</guid>
            <category><![CDATA[load-balancer]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[api]]></category>
            <category><![CDATA[gateway]]></category>
            <category><![CDATA[endpoints]]></category>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Tue, 30 Jul 2024 08:43:52 GMT</pubDate>
            <atom:updated>2024-07-30T08:43:52.444Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/250/1*sHNwxXfNeOtNhgZfD6IZyQ.png" /><figcaption>Loadbalancer</figcaption></figure><p>In software development, terms like API, endpoint, gateway, and load balancer are frequently used. However, these terms can be confusing, especially for those new to the field. This article will demystify these concepts with clear definitions and practical examples.</p><h4><strong>API (Application Programming Interface)</strong></h4><p>An API is a set of rules and protocols that enable software applications to communicate with each other. It defines the methods and data formats that applications can use to request and exchange information. APIs are crucial for integrating different systems and allowing them to work together seamlessly.</p><p><strong>Example:</strong><br>When you use a weather application on your smartphone to check the weather, the app connects to a remote server using an API to get the most up-to-date weather information. The API specifies how the app can ask for weather data and in what format the server will provide the information..</p><h4>Endpoint</h4><p>An endpoint is a specific URL that provides access to a particular function or resource within an API. It serves as one end of a communication channel through which an API interacts with another system. Endpoints are crucial for retrieving or sending data via the API..</p><p><strong>Example:</strong><br>In a RESTful API, an endpoint could be a URL that enables you to retrieve user information. For example:</p><pre>https://api.example.com/users<br></pre><p>Here, “https://api.example.com” is the base URL, and “/users” is the endpoint that returns information about users.</p><h4>Gateway (API Gateway)</h4><p>An API Gateway is a server that acts as an intermediary for requests from clients who are looking for resources from other servers. It handles all the tasks involved in accepting and processing numerous API calls, including traffic management, authorization and access control, monitoring, and API version management. The gateway routes different requests, transforms protocols, and manages authentication and rate limiting.</p><p><strong>Example:</strong><br>Just to recap, in this scenario, we have an e-commerce platform that consists of different microservices to manage user accounts, product catalogues, and orders. The API Gateway acts as an intermediary between the client applications (like web and mobile apps) and these microservices. When a user makes a purchase, the request is transmitted through the API Gateway, which then directs it to the relevant microservice.</p><h4>Load Balancer</h4><p>A load balancer is a device or software that evenly distributes incoming network or application traffic across multiple servers. This helps prevent any single server from being overloaded with too much traffic, thus improving the responsiveness and availability of applications. Load balancers can distribute traffic using different algorithms, such as round-robin, the least connections, or IP hash.</p><p><strong>Example:<br></strong>Consider a popular streaming service that needs to serve millions of users simultaneously. To ensure a smooth viewing experience, a load balancer distributes incoming video stream requests across multiple servers. If one server becomes too busy, the load balancer routes new requests to less busy servers, maintaining optimal performance.</p><h4>Conclusion</h4><p>Understanding the roles of APIs, endpoints, gateways, and load balancers is essential for anyone involved in software development or IT. APIs enable communication between different software systems, endpoints define specific access points within APIs, gateways manage and route API requests and load balancers ensure even distribution of traffic across servers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e16322f38113" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Step-by-Step Beginner’s Guide: Setting Up Ubuntu 20 LTS in VirtualBox with Vagrant]]></title>
            <link>https://towardsdev.com/step-by-step-beginners-guide-setting-up-ubuntu-20-lts-in-virtualbox-with-vagrant-0923507f519c?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/0923507f519c</guid>
            <category><![CDATA[vagrant]]></category>
            <category><![CDATA[virtual-machine]]></category>
            <category><![CDATA[virtualbox]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[beginner]]></category>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Tue, 26 Dec 2023 10:13:11 GMT</pubDate>
            <atom:updated>2023-12-26T17:25:44.640Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/795/1*Ic_ofX5Dt09n9rpZiDiMzg.png" /></figure><p>Setting up Vagrant on Ubuntu within a VirtualBox environment is a powerful way to manage and create development environments.</p><p>Vagrant simplifies the process of configuring and provisioning virtual machines, allowing for consistent development setups across teams.</p><p>In this tutorial, we will be taking the easy steps to setting up Ubuntu 20 using Vagrant on a Virtualbox:</p><h4>Prerequisites:</h4><p><strong>1. VirtualBox:</strong></p><p><a href="https://www.virtualbox.org/">VirtualBox</a> is a virtualization product that is suitable for both home and enterprise use. It is freely available as Open Source Software under the GNU General Public License (GPL) version 3.</p><p>Ensure it’s installed on your machine. It can easily be downloaded and installed from the official website. There is a link to the installation <a href="https://www.virtualbox.org/wiki/Downloads">packages</a>.</p><p><strong>2. Vagrant:</strong></p><p><a href="https://www.vagrantup.com/">Vagrant</a> is a command line utility that manages virtual machine lifecycles, enabling the creation and configuration of lightweight, reproducible, and portable development environments.</p><p>It can be installed by downloading the package from the <a href="https://developer.hashicorp.com/vagrant/install">official website </a>or via the terminal in Linux using the command below:</p><pre><br> sudo apt install vagrant<br> </pre><h4>Setting up a Vagrant environment</h4><p><strong>1. Create a directory:<br></strong> Open your terminal and create a new directory where you want to store your Vagrant configuration and related files.</p><pre><br> mkdir my_vagrant_project<br> cd my_vagrant_project<br> </pre><p><strong>2. Initialize Vagrant:</strong></p><p>Inside the directory, initialize Vagrant to create a Vagrantfile, which defines the configuration of your virtual environment.</p><pre><br>vagrant init ubuntu/focal64</pre><p><strong>3. Start the Virtual Machine:</strong></p><p>Run the following command within your project directory to start the VM based on the Vagrantfile configuration.</p><pre><br> vagrant up</pre><p>That should set up the Ubuntu 20 LTS automatically in the Virtualbox.</p><p><strong>5. Access and Interact with the Virtual Machine:</strong></p><p>Open your virtual box and see that the &quot;Ubuntu 20.04 LTS&quot; is already running. It may require a login and password. For those, as explained in the official <a href="https://developer.hashicorp.com/vagrant/docs/boxes/base#vagrant-user">guide</a>, please use:</p><pre>user: vagrant<br>password: vagrant</pre><p>Now you’re inside the VM, and you can use it as a separate Ubuntu environment. Make changes, install software, or set up your development environment within this VM.</p><p>Customizing the Vagrantfile enables complex setups, with specific configurations for provisioning, syncing folders, and more.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0923507f519c" width="1" height="1" alt=""><hr><p><a href="https://towardsdev.com/step-by-step-beginners-guide-setting-up-ubuntu-20-lts-in-virtualbox-with-vagrant-0923507f519c">Step-by-Step Beginner’s Guide: Setting Up Ubuntu 20 LTS in VirtualBox with Vagrant</a> was originally published in <a href="https://towardsdev.com/">Towards Dev</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Building a Beginner-Friendly CRUD API with Golang: Step-by-Step Guide]]></title>
            <link>https://blog.stackademic.com/building-a-beginner-friendly-crud-api-with-golang-step-by-step-guide-f30d6afe3f2e?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/f30d6afe3f2e</guid>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Sun, 27 Aug 2023 10:37:40 GMT</pubDate>
            <atom:updated>2023-12-26T11:15:53.027Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/980/1*0HCP8S7YOgzvUeZkTj0rCA.png" /></figure><p>Using MySQL databases, we’ll create a Golang-based CRUD API to manage club members’ details. Explore modern web development with Golang as we demystify crafting a Beginner-Friendly CRUD API. This guide unveils Go programming and API design, empowering you to create a robust CRUD API from scratch.</p><h4>Golang:</h4><p>Go or Golang is a programming language created by Google. It’s known for its simplicity, efficiency, and concurrent programming capabilities. It has garbage collection and concurrency, perfecting system programming and web development.</p><p>Go can be installed easily using the guidelines in the official <a href="https://go.dev/doc/install">documentation</a>.</p><h4>MySQL:</h4><p>MySQL is an open-source relational database system that efficiently stores and manages structured data for various applications, from small projects to enterprise systems. It can be installed using the official <a href="https://dev.mysql.com/doc/mysql-installation-excerpt/5.7/en/">guidelines</a>.</p><p><strong>STEPS:</strong></p><ol><li><strong>Initialize Go:</strong></li></ol><p>Begin by creating your project folder or directory. Within this directory, initiate a Go server. Personally, I recommend initializing it through a GitHub repository but feel free to choose any preferred module.</p><pre>//Create a work directory and move into the folder<br>mkdir clubTeam &amp;&amp; cd clubTeam<br><br>//Initialize Go modules in the folder<br>go mod init github.com/&lt;username&gt;/repo.com<br><br>//Also can be<br>go mod init &lt;yourmodule.com&gt;</pre><p><strong>2. Import the packages:</strong></p><p>In this guide, we will require the GORM and Gorilla Mux packages:</p><p>a. <strong>GORM<em> </em></strong>is a widely used Go package for Object-Relational Mapping (ORM), streamlining database interactions by utilizing Go structs and methods to manage relational databases. It improves data manipulation, retrieval, and querying while enhancing code organization and maintainability. More details on GORM are available in the official <a href="https://gorm.io/docs/">documentation</a>.</p><p>We must also import the MySQL dialect from GORM since we are using the MySQL database.</p><pre>go get &quot;github.com/jinzhu/gorm&quot;<br><br>go get &quot;github.com/jinzhu/gorm/dialects/mysql&quot;<br></pre><p>b. <a href="https://github.com/gorilla/mux"><strong>Gorilla Mux</strong></a> is a powerful Go package for HTTP routing, simplifying the mapping of incoming requests to handlers with a flexible syntax. It’s popular for building web apps, offering clean routes, URL parameter management, and effective HTTP method handling.</p><pre>go get &quot;github.com/gorrilla/mux&quot;</pre><p>With our packages imported, we’re ready to establish the project structure.</p><p><strong>3. Organizing the Folders:</strong><br>We will set up a <strong><em>main</em></strong> folder and a <strong><em>pkg</em></strong> folder. The main folder hosts the server’s main.go file.<br>Inside the <strong><em>pkg</em></strong> folder, we’ll arrange five sub-folders to manage distinct concerns, enhancing code organization and readability.</p><p>Within the <strong><em>pkg</em></strong> folder, we’ll have:</p><p>a. config &gt; config.go<br>b. controllers &gt; member-controller.go<br>c. models &gt; member-model.go<br>d. utils &gt; utils.go<br>e. routes &gt; member-routes.go</p><p><strong>4. Streamlining the Process: Let’s Begin with Routes:</strong></p><p>We will kick off by defining our routes, and keeping logic minimal. In the <strong><em>member-routes.go</em></strong> file within the <strong><em>routes</em></strong> folder, we’ll utilize the Gorilla Mux package. As previously mentioned, this package plays a crucial role in handling API routing.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/096f9198c305ce3d090f5791fc000d70/href">https://medium.com/media/096f9198c305ce3d090f5791fc000d70/href</a></iframe><p>The above sets up routes using Gorilla Mux for managing CRUD operations on a “member” resource within a web app.</p><p><strong>Key points:</strong></p><p><strong><em>A. Imports: In the “routes” package, it imports external packages:</em></strong></p><ul><li>&lt;yourmodule.com&gt;pkg/controllers: Imports &quot;controllers&quot; from &quot;workers&quot; project.</li><li>github.com/gorilla/mux: Imports Gorilla Mux router for HTTP routing.</li></ul><p><strong><em>B. MembersRoutes Function: Named “MembersRoutes,” it configures routes to handle various HTTP methods for “member” actions:</em></strong></p><ul><li>Route Definitions:</li><li>router.HandleFunc(&quot;/member&quot;, controllers.CreateMember).Methods(&quot;POST&quot;): POST route for creating members.</li><li>router.HandleFunc(&quot;/member&quot;, controllers.GetMember).Methods(&quot;GET&quot;): GET route for retrieving all members.</li><li>router.HandleFunc(&quot;/member/{memberId}&quot;, controllers.GetMemberById).Methods(&quot;GET&quot;): GET route for fetching a member by ID.</li><li>router.HandleFunc(&quot;/member/{memberId}&quot;, controllers.UpdateMember).Methods(&quot;PUT&quot;): PUT route for updating a member by ID.</li><li>router.HandleFunc(&quot;/member/{memberId}&quot;, controllers.DeleteMember).Methods(&quot;DELETE&quot;): DELETE route for deleting a member by ID.</li></ul><p><strong>5. Connect with Database:</strong></p><p>With our routes defined, it’s time to establish a connection to the database.<br>It’s recommended to have MySQL running locally, and the corresponding database set up. In the config.go file, ensure to input your MySQL username, password, and the database name.</p><p>In the config &gt; config.go file:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a58d8019fed3995107636ab34727ab11/href">https://medium.com/media/a58d8019fed3995107636ab34727ab11/href</a></iframe><p>The <strong>config</strong> package manages MySQL database configuration and connection through GORM. It involves:</p><p><strong><em>A. Imports: The package imports essential libraries:</em></strong></p><ul><li>github.com/jinzhu/gorm: GORM, an ORM framework for Go.</li><li>_ &quot;github.com/jinzhu/gorm/dialects/mysql&quot;: Imports MySQL dialect for GORM with a side effect.</li></ul><p><strong><em>B. Database Setup: It establishes and maintains a MySQL connection:</em></strong></p><ul><li>Connect() uses gorm.Open for connection, including user info, host, etc.</li><li>Errors trigger program panic.</li><li>Database Access: The db variable (type *gorm.DB) holds the connected instance post Connect().</li></ul><p><strong><em>C. GetDB Function: </em></strong><strong><em>GetDB() offers access to </em></strong><strong><em>db, facilitating database operations:</em></strong></p><p>In short, <strong>config</strong> manages MySQL connectivity via GORM. Connect() initializes, GetDB() grants access, enabling efficient database management.</p><p><strong>6. Creating models:</strong></p><p>We will create the models for our data in the model &gt; member-model.go</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/92794b93c989731c94ba010bc1a5fc02/href">https://medium.com/media/92794b93c989731c94ba010bc1a5fc02/href</a></iframe><p>The <strong>models</strong> package facilitates database interactions for a <strong><em>Member </em></strong>entity. Here’s a concise overview:</p><ul><li><strong>Database Setup</strong>: The package uses GORM and custom configuration for database operations. It initializes the GORM database and sets up the <strong><em>Member</em></strong> struct to define attributes.</li><li><strong>Member Entity</strong>: <strong><em>Member</em></strong> struct represents a member with name, email, country, and color. GORM tags enable JSON serialization and link to database properties.</li><li><strong>Initialization</strong>: The init() function connects to the database using custom settings and auto-migrates to create the <strong><em>Member</em></strong> table.</li><li><strong>CreateMember Method</strong>: Adds a new member to the database and returns the created member’s pointer.</li><li><strong>GetAllMembers Function</strong>: Retrieves all members as a slice of <strong><em>Member</em></strong> objects from the database.</li><li><strong>GetMemberById Function</strong>: Fetches a specific member by ID and provides details along with the database query reference.</li><li><strong>DeleteMember Function</strong>: Removes a member by ID from the database and returns the deleted member.</li></ul><p>In short, the <strong>models</strong> package manages database actions for <strong><em>Member</em></strong> data, enabling CRUD operations through GORM</p><p><strong>7. We craft the Utils:</strong></p><p>Considering our data is stored as JSON in the model, we will require utilities to handle both “unmarshaling” JSON requests from users and the database.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1aec1cf55c9df53d1f7a07a6ea47a447/href">https://medium.com/media/1aec1cf55c9df53d1f7a07a6ea47a447/href</a></iframe><p>The ParseBody function efficiently extracts JSON data from an HTTP request body and fills a flexible interface x. The process involves:</p><ul><li><strong>Importing necessary packages</strong> for managing JSON data and handling HTTP requests (encoding/json and io/ioutil).</li><li><strong>Defining the ParseBody function</strong>, which takes an HTTP request (r *http.Request) and an interface (x interface{}) as parameters.</li><li><strong>Reading the request body using ioutil.ReadAll</strong>, storing it as a byte slice named body, and proceeding if no reading errors occur.</li><li><strong>Unmarshaling (converting)</strong> the JSON data in the body byte slice into the provided interface x using json.Unmarshal.</li><li><strong>Handling successful unmarshaling </strong>by storing the parsed JSON data within interface x.</li><li><strong>Handling errors</strong> during body reading or JSON unmarshaling without changing the value of x, thus preserving its original state.</li></ul><p>In essence, the ParseBody function streamlines the extraction and conversion of JSON data from an HTTP request body to a versatile interface x. It simplifies the process while handling potential errors, ensuring that the JSON data structure matches the expected interface x structure.</p><p><strong>8. Now, it’s a fitting time to generate the Controller responsible for managing API function calls.</strong></p><p>In the controller &gt; member-controller.go:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/369fcfd531620e08f3aef44c8dcf141d/href">https://medium.com/media/369fcfd531620e08f3aef44c8dcf141d/href</a></iframe><p>The above code in Go defines a collection of HTTP handler functions responsible for managing various CRUD (Create, Read, Update, Delete) operations for a “Member” resource. <br>The handlers use the Gorilla Mux router for routing HTTP requests to the appropriate functions. Here’s an explanation of each function:</p><ol><li><strong><em>CreateMember:</em></strong><br> — HTTP Method: POST<br> — Path: “/members”<br> — Description: Creates a new member by parsing the request body JSON into a model structure — <em>Member struct</em>. <br>It then calls the <em>CreateMember</em> method on the struct to create and store the new member. Serializes the created member into JSON format and sends it as the response.</li><li><strong><em>GetAllMembers</em></strong><em>:</em><br> — HTTP Method: GET<br> — Path: “/members”<br> — Description: Retrieves a list of all members by calling the <em>GetAllMembers</em> function from the models’ package. Serializes the list into JSON format and sends it as a response.</li><li><strong><em>GetMemberById:</em></strong><br> — HTTP Method: GET<br> — Path: “/members/{memberId}”<br> — Description: Retrieves details of a specific member by their ID. <br>It extracts the <em>memberId</em> from the request’s URL parameters using Gorilla Mux. It then converts the ID to an integer and uses it to call the <em>GetMemberById</em> function from the models’ package. Serializes the member details into JSON format and sends it as a response.</li><li><strong><em>DeleteMember:</em></strong><br> — HTTP Method: DELETE<br> — Path: “/members/{memberId}”<br> — Description: Deletes a member by their ID. It extracts the <em>memberId</em> from the request’s URL parameters using Gorilla Mux. It then converts the ID to an integer and uses it to call the <em>DeleteMember</em> function from the <em>models</em> package. Serializes the deleted member into JSON format and sends it as the response.</li><li><strong><em>UpdateMember:</em></strong><br> — HTTP Method: PUT<br> — Path: “/members/{memberId}”<br> — Description: Updates an existing member’s details. <br>It extracts the <em>memberId</em> from the request’s URL parameters using Gorilla Mux. It then converts the ID to an integer and uses it to call the <strong><em>GetMemberById</em></strong> function from the `model` package to retrieve the current member details. <br>It parses the request body JSON into <em>a models.Member</em> struct for the updated data. <br>It then updates the member’s attributes with the new values if provided (name, email, country, color), saves the changes to the database, and serializes the updated member details into JSON format to send as the response.</li></ol><p>In addition to the CRUD operations, each handler function sets the HTTP response status code and content type header appropriately before writing the response.</p><p><strong>9. Establish a Connection with the Main Server:</strong></p><p>It is time to connect with the main server file:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9ec42b0d2ec0770e0d2a4298d451fdf8/href">https://medium.com/media/9ec42b0d2ec0770e0d2a4298d451fdf8/href</a></iframe><p><strong>10. Compile and Run Your Go Project:</strong></p><p>With the entire package configured, it’s time to perform a test. Head to the main folder and execute the following command:</p><pre>//Move to the Man folder<br>cd main<br><br><br>//Compile the Go server binary file<br>go build</pre><p>This action generates a main binary file.<br>Additionally, within the main folder, execute the package:</p><pre>go run main.go</pre><p>At this point, we can proceed to Postman for API testing.</p><p><strong>11. Testing API using Postman:</strong></p><p><strong>a. CreateMember:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/710/1*isFytwXJDk8kQfdUgMkRww.png" /><figcaption>Image for Create a member request on Postman</figcaption></figure><p><strong>b. GetAllMembers:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/1*xzccwP_mYBMCwm74DpECrg.png" /><figcaption>Image for Get all members request on Postman</figcaption></figure><p><strong>c. GetMemberById:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/709/1*Q3GZY6H9823DUNeWXFZvnQ.png" /><figcaption>Image for Get a member by Id request on Postman</figcaption></figure><p><strong>d. UpdateMember:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/712/1*TeFW1y3mpHxd0QYpEKhd-Q.png" /><figcaption>Image for Update a member request on Postman</figcaption></figure><p>Congratulations on the successful execution of all the requests on Postman!<br> The outcomes are in line with our expectations. Keep up the great work and embrace the learning process!</p><h3>Stackademic</h3><p><em>Thank you for reading until the end. Before you go:</em></p><ul><li><em>Please consider </em><strong><em>clapping</em></strong><em> and </em><strong><em>following</em></strong><em> the writer! 👏</em></li><li><em>Follow us on </em><a href="https://twitter.com/stackademichq"><strong><em>Twitter(X)</em></strong></a><em>, </em><a href="https://www.linkedin.com/company/stackademic"><strong><em>LinkedIn</em></strong></a><em>, and </em><a href="https://www.youtube.com/c/stackademic"><strong><em>YouTube</em></strong></a><strong><em>.</em></strong></li><li><em>Visit </em><a href="http://stackademic.com/"><strong><em>Stackademic.com</em></strong></a><em> to find out more about how we are democratizing free programming education around the world.</em></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f30d6afe3f2e" width="1" height="1" alt=""><hr><p><a href="https://blog.stackademic.com/building-a-beginner-friendly-crud-api-with-golang-step-by-step-guide-f30d6afe3f2e">Building a Beginner-Friendly CRUD API with Golang: Step-by-Step Guide</a> was originally published in <a href="https://blog.stackademic.com/">Stackademic</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Creating a beginner-friendly CRUD API using Node.js, Express, and MySQL]]></title>
            <link>https://blog.stackademic.com/creating-a-beginner-friendly-crud-api-using-node-js-express-and-mysql-2d292ca8b4b?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d292ca8b4b</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[mysql]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[expressjs]]></category>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Mon, 21 Aug 2023 16:42:21 GMT</pubDate>
            <atom:updated>2023-08-21T16:42:21.913Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/640/1*AVLf3avTxFZcf0gojCdfXA.png" /></figure><p>We can create a remarkable CRUD API using MySQL, Node.js, and Express that empowers users to build their own food menus effortlessly. In this article, we can easily manage and update food information, such as names, categories, prices, and descriptions.</p><p>We will also implement the search for food in the menu using the name string.</p><p><strong>Node.js</strong> is an open-source, cross-platform JavaScript runtime environment. It allows developers to execute JavaScript code on the server, enabling them to build scalable and efficient network applications. There are more details on the official <a href="https://nodejs.org/en">documentation</a>.</p><p><strong>Express</strong> is a fast and minimalistic web application framework for Node.js. It simplifies the creation of web apps and APIs by offering a wide range of features and tools. With Express developers can easily manage routing, middleware, and HTTP requests in a structured and organized manner. Everything about the installation and documentation can be found on the <a href="https://expressjs.com/">link</a>.</p><p><strong>MySQL</strong> is an open-source relational database management system (RDBMS) that offers a structured and efficient way to store, manage, and retrieve data. You can find the comprehensive installation guide in the <a href="https://www.mysql.com/">documentation</a>.</p><h4><strong>Pre-requisite:</strong></h4><ol><li>MySQL installed</li></ol><p>2. Basic knowledge of Node.js and Express</p><p>3. Essential SQL Command Knowledge</p><h4>Steps:</h4><ol><li><strong>Initializing:</strong><br>Create a directory, move into the directory and install the node package manager.</li></ol><pre>mkdir mysql-food-menu<br><br>cd mysql-food-menu<br><br>npm init -y</pre><p>This should create a <em>package.json</em> file.</p><p>2. <strong>Install Dependencies:</strong></p><p>To establish a connection to the database, we will install MySQL, and for the server connection, we will use Express.</p><pre>npm install mysql express --save</pre><p>3. <strong>Folder arrangement:</strong></p><p>Let us create the needed folders for handling the database connection, API controllers and routes separately.</p><p>i. <em>connection</em> folder which should contain <em>database.sql</em> and <em>dbconnection.js- </em>This will handle all the connections to the database and table.</p><p>ii. <em>controller</em> folder which contains the <em>itemController.js </em>file. This handles the function calls to API.</p><p>iii. <em>router </em>folder which contains<em> the itemroutes.js </em>file. This handles the routes for interacting with the server.</p><p>iv <em>index.js</em> is the server file.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/169/1*WYG0HFCxvQ0Rgi6qm7XPeQ.png" /><figcaption>Folder arrangement</figcaption></figure><p>4. <strong>Setting up the server file:</strong></p><p>Open the index.js file and add the express server. Set it to listen to a port. We will be using port 2090.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/69fe8d1d809208ae1823f4d5b075f1ed/href">https://medium.com/media/69fe8d1d809208ae1823f4d5b075f1ed/href</a></iframe><p>In the directory, open a terminal, and run the command: <em>node index.js.</em></p><pre>node index.js</pre><p>You should see the Message logged <strong><em>Server is listening to port 2090</em></strong></p><p><strong>5. Connecting with the database:</strong></p><p>We need to ensure that the MySQL server is active. Then log in and create the database and the corresponding table.</p><p>Open the database.sql file and insert commands for creating a database called <strong><em>kitchen</em></strong> and inside the database, create a table called <strong><em>menu</em></strong>.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/5798d0c00f343ef8e00f8218a45e9e57/href">https://medium.com/media/5798d0c00f343ef8e00f8218a45e9e57/href</a></iframe><p>The <strong><em>menu</em></strong> table has columns for a unique identifier <strong><em>menuId, name, category, price and description</em></strong>. <br>Run these commands in the MySQL terminal after successfully logging in with your MySQL details.</p><p>Now is a good time to set up the connection with the MySQL server. Open the dbconnection.js file, we create a connection with the MySQL server.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/dc1c5bc6dfa5d5ca49ba60d5d2a08730/href">https://medium.com/media/dc1c5bc6dfa5d5ca49ba60d5d2a08730/href</a></iframe><p>This code establishes a connection to a MySQL database using the <strong><em>mysql</em></strong> Node.js module. <br>It sets up the connection details including the <strong><em>host, user, password, </em></strong>and<strong><em> database name</em></strong>. <br>The <strong><em>mysqlConnection.connect</em></strong> function is used to attempt a connection, and if successful, it logs a message confirming the connection. If the connection fails, it logs an error message with the details of the error.</p><p>6<strong>. Set up the controller:</strong></p><p>Open the <strong><em>itemcontroller.js</em></strong> file in the controller folder. We create the <em>addItem, getAllItems, getOneItemById, getAllItemsByName, updateOneItem</em> and <em>deleteOneItem</em> functions.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1825e600b2d1ade35a4ffc4d3e3c40df/href">https://medium.com/media/1825e600b2d1ade35a4ffc4d3e3c40df/href</a></iframe><p>Here’s a summary of each function:</p><p>A. <strong><em>addItem:</em></strong> This function adds a new menu item to the database. It extracts information like name, category, price, and description from the request body and inserts them into the “menu” table. It responds with a success message and inserted values, or an error message if there’s an issue.</p><p>B. <strong><em>getAllItems:</em></strong> This function retrieves all menu items from the database. It executes a SQL query to select all records from the “menu” table and responds with the retrieved data or an error message.</p><p>C. <strong><em>getOneItemById:</em></strong> This function retrieves a single menu item based on its ID. It retrieves the item’s ID from the request parameters, queries the database for all matching items, and responds with the item’s details or appropriate error messages if the item is not found.</p><p>D. <strong><em>getAllItemsByName:</em></strong> This function retrieves all menu items that have a name matching a specified string. It takes the name as a parameter, constructs a SQL query with a LIKE condition, queries the database, and responds with the matching items or error messages.</p><p>E. <strong><em>updateOneItem:</em></strong> This function updates the details of a menu item. It takes the item’s ID and updated information from the request parameters and body. It first checks if the item exists, and if it does, it performs an update operation on the item’s details. It responds with a success message or error message.</p><p>F. <strong><em>deleteOneItem: </em></strong>This function deletes a menu item from the database. It takes the item’s ID from the request parameters, checks if the item exists, and if it does, performs a delete operation. It responds with a success message or error message.</p><p>Each function includes error handling to catch and respond to potential issues, such as database errors or missing items. These functions serve as an API for managing menu items in the restaurant’s database.</p><p><strong>7. Set up the Routes:</strong></p><p>In the <strong><em>itemroutes.js</em></strong> file; we create the routes for the API call.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/19da843ce41fb8e77455643ab0bf6f59/href">https://medium.com/media/19da843ce41fb8e77455643ab0bf6f59/href</a></iframe><p>The routes are designed to correspond with the appropriate HTTP methods. Now would be a good time to update the server file with the routes.</p><p><strong>8. Update the Server file:</strong></p><p>To enable the server to utilize the routes, all we need to do is import the itemroutes.js file and then harness the power of the app.use() method. Our index.js server file should look like:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/06bf55a9575d8a389040d23985f9f503/href">https://medium.com/media/06bf55a9575d8a389040d23985f9f503/href</a></iframe><p>Open the terminal and run the command:</p><pre>node index.js</pre><p>You should see the logs in the terminal:<br><strong><em>Server is listening to port 2090 </em></strong>and<strong><em> Connection Established Successfully.</em></strong></p><p><strong>9: Testing in Postman:</strong></p><p><strong><em>a. Add Item:</em></strong></p><figure><img alt="Screenshot from Postman showing the Create an Item method" src="https://cdn-images-1.medium.com/max/710/1*0pRThwjuscASN8jPK2yW4g.png" /></figure><p><strong><em>b. getAllItems:</em></strong></p><figure><img alt="Screenshot from Postman showing the get all Item route method" src="https://cdn-images-1.medium.com/max/704/1*VJLevMxe7oDx3i0fWT4CLA.png" /></figure><p><strong><em>c. getOneItemById:</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/708/1*1SmmzDNkwanff5yB2-ytMw.png" /></figure><p><strong><em>d. getAllItemsByName:</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/704/1*MQ4h8gmqIMasbQrnWtr3Sw.png" /></figure><p><strong><em>e. updateOneItem:</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/709/1*vSJjpyBqILG66cMKGSW_EQ.png" /></figure><p><strong><em>f. deleteOneItem:</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/699/1*KWq4oIgtX1Rz69VAFr3Cqg.png" /></figure><p><em>Thank you for reading until the end. Please consider following the writer and this publication. Visit </em><a href="https://stackademic.com/"><em>Stackademic</em></a><em> to find out more about how we are democratizing free programming education around the world.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2d292ca8b4b" width="1" height="1" alt=""><hr><p><a href="https://blog.stackademic.com/creating-a-beginner-friendly-crud-api-using-node-js-express-and-mysql-2d292ca8b4b">Creating a beginner-friendly CRUD API using Node.js, Express, and MySQL</a> was originally published in <a href="https://blog.stackademic.com/">Stackademic</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Create a CRUD API using Node.js, Express and PostgreSQL]]></title>
            <link>https://blog.devgenius.io/create-a-crud-api-using-node-js-express-and-postgresql-51041cb16e46?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/51041cb16e46</guid>
            <category><![CDATA[api]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[beginner]]></category>
            <category><![CDATA[postgres]]></category>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Sun, 13 Aug 2023 12:19:08 GMT</pubDate>
            <atom:updated>2023-08-14T15:13:25.325Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UW_9OOQYuPWHvt4QuXOLlA.png" /></figure><p>We will build a CRUD API of Notes with Node.js, Express, and PostgreSQL.</p><p>Node.js serves as an outstanding open-source runtime environment, empowering the execution of JavaScript code on the server side. This facilitates the seamless and scalable development of network applications and web services. More details can be found in the official <a href="https://nodejs.org/en">documentation</a>.</p><p>Express.js is a minimalist and flexible web application framework for Node.js, designed to simplify the creation of robust and efficient web APIs and applications. It can be installed using the Node Package Manager. There is more about it in the <a href="https://expressjs.com/">documentation</a>.</p><p><strong>PostgreSQL</strong> is a powerful open-source RDBMS valued for extensibility, reliability, and advanced SQL support, popular for data storage in diverse applications.</p><p><strong>Pre-requisite:</strong><br>The only prerequisite is a basic understanding of Node.js and PostgreSQL. You might also need to install PostgreSQL on your local machine.</p><p>This tutorial will guide you through building a simple Note app. This app enables users to CREATE, READ, UPDATE, and DELETE notes stored in a PostgreSQL database.</p><p><strong>Folder Structure: </strong><br>We require the following components:</p><p>a. A controller folder containing noteController.js. <br>b. A database.sql file for the database and table creation commands.<br>c. db.js for PostgreSQL pool initialization. <br>d. The main server file named index.js</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/167/1*9NVt-6AvpDvVy35W6hL8MQ.png" /></figure><p><strong>STEPS:</strong><br><strong><em>1. Initialize the Node server</em></strong></p><pre>npm init -y</pre><p>This command generates a package.json file.</p><p><strong><em>2. Install Express and node-postgres</em></strong></p><pre>npm install express pg</pre><p>This generates the node_modules directory and potentially creates package-lock.json.</p><p><strong><em>3.</em></strong> <strong><em>Initialize the server file </em></strong>by navigating to index.js</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/8fbf44dedde2449154ea032f2829a3c3/href">https://medium.com/media/8fbf44dedde2449154ea032f2829a3c3/href</a></iframe><p>Open the terminal, move to the project folder and run</p><pre>node index.js</pre><p>Upon execution, it will log “Server is running on port 8989” to the terminal.</p><p><strong><em>4. Let’s generate the database and project table</em></strong>. I suggest including the command in the file before running it in the terminal, reducing the likelihood of errors. Navigate to the Database.sql file.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c78fbce854af7f5f39622e574894ef2b/href">https://medium.com/media/c78fbce854af7f5f39622e574894ef2b/href</a></iframe><p>a. Open the terminal, and log in to the <em>postgres</em> using your details.</p><p>Then type <strong><em>psql</em></strong> in the terminal to be able to run the commands below:</p><pre>sudo -i -u postgres<br><br>psql</pre><p>b. Create a database named <strong><em>notestutorial</em></strong>;</p><pre>CREATE DATABASE notestutorial;</pre><p>c. Move into that database and then create a database table with these two commands:</p><pre>//Move into the database//<br><br><br>\c notestutorial;<br><br><br>//Create a table//<br><br><br>CREATE TABLE note(<br>    note_id SERIAL PRIMARY KEY,<br>    description VARCHAR(255)<br>);</pre><p><strong><em>5. Establish a node-postgres connection for database interaction.</em></strong><br>Navigate to the <em>db.js</em> file:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/a07297f9976126d7890dd71e17e2249c/href">https://medium.com/media/a07297f9976126d7890dd71e17e2249c/href</a></iframe><p>The above code sets up a PostgreSQL connection using the “pg” library’s Pool object. The pool instance is configured and exported for broader use. Here&#39;s a brief overview:</p><p>a. Import Pool Object: Import Pool from &quot;pg&quot; to manage PostgreSQL connections.</p><p>b. Configure Connection: Configure pool with user, password, host, port, and database.</p><p>c. Create pool Instance: Instantiate Pool using provided configuration.</p><p>d. Export pool: Export pool instance for easy access in other app parts.</p><p>It configures and exports pool for widespread use, optimizing concurrent database operations.</p><p><strong><em>6. Set up the Controller:</em></strong></p><p>We will create the controller to manage the API function calls.<br>Open the <em>notecontroller.js</em> file within the <em>controller</em> directory:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/d2c86666df450b29868679fb55d002a1/href">https://medium.com/media/d2c86666df450b29868679fb55d002a1/href</a></iframe><p>The above code features asynchronous functions for CRUD operations on a “note” entity through a database. The pool object from the &quot;db&quot; module handles database queries. Here&#39;s a concise explanation:</p><p>createNote Function: Creates a new note.</p><ul><li>Parameters: req (request object), res (response object).</li><li>Extracts description from the request body.</li><li>Executes an SQL INSERT query via pool.query to add a note, responding with the new data.</li></ul><p>getAllNotes Function: Retrieves all notes.</p><ul><li>Parameters: req, res.</li><li>Executes an SQL SELECT query via pool.query to fetch all records, responding with an array of notes.</li></ul><p>getOneNote Function: Retrieves a single note by note_id.</p><ul><li>Parameters: req, res.</li><li>Uses the note_id from request parameters.</li><li>Executes an SQL SELECT query via pool.query with a WHERE clause, responding with the requested note.</li></ul><p>updateOneNote Function: Updates an existing note.</p><ul><li>Parameters: req, res.</li><li>Extracts note_id and description from request parameters and body.</li><li>Executes an SQL UPDATE query via pool.query to modify the note description, responding with an update message.</li></ul><p>deleteOneNote Function: Deletes a note.</p><ul><li>Parameters: req, res.</li><li>Extracts note_id from request parameters.</li><li>Executes an SQL DELETE query via pool.query to remove a note, responding with a deletion message.</li></ul><p>Each function is enclosed in a try...catch block for error handling. Errors trigger console log messages. This code establishes a foundation for CRUD operations on a &quot;note&quot; entity via a PostgreSQL database connection pool.</p><p><strong><em>7. Complete the server file:</em></strong></p><p>Now the final step is the write the API requests in the server file.</p><pre><br>app.post(&quot;/notes&quot;, noteController.createNote)<br><br>app.get(&quot;/notes&quot;, noteController.getAllNotes)<br><br>app.get(&quot;/notes/:id&quot;, noteController.getOneNote)<br><br>app.put(&quot;/notes/:id&quot;, noteController.updateOneNote);<br><br>app.delete(&quot;/notes/:id&quot;, noteController.deleteOneNote)</pre><p>As a result, the index.js server file will resemble the following:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/1d068e791369fb19a003ee9e6a02c04a/href">https://medium.com/media/1d068e791369fb19a003ee9e6a02c04a/href</a></iframe><p>Now, we have completed the CRUD API, we can run our server and test the API on Postman.</p><p><strong>Testing the API</strong><br>Open the Postman application and enter the Routes:<br><strong><em>a. Create a Note</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/845/1*LeHrnYxytJijIFLpeBzhGQ.png" /></figure><p><strong><em>b. Get All Notes:</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/842/1*MLFPB28ok_HKaht4b118Kg.png" /></figure><p><strong><em>c. Get a Note by ID:</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/851/1*YfJRInzwHSeyGE_6r_-ZRA.png" /></figure><p><strong><em>d. Update a Note:</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/848/1*qDQHt5veEpoTnhSt25gFdQ.png" /></figure><p><strong><em>e. Delete One Note:</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/847/1*twPE-zSsGz32RLODFcEDng.png" /></figure><p><strong><em>Conclusion:</em></strong><br>With our combination of Node.js, Express, and PostgreSQL, we have created a powerful CRUD API for managing notes. This showcases the incredible possibilities of modern web development and provides effortless control over your data. As we explore the evolving landscape of web app creation, the knowledge gained here will serve as a solid foundation for future progress.</p><p>Happy Hacking =)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=51041cb16e46" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/create-a-crud-api-using-node-js-express-and-postgresql-51041cb16e46">Create a CRUD API using Node.js, Express and PostgreSQL</a> was originally published in <a href="https://blog.devgenius.io/">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to install PostgreSQL using Terminal on Ubuntu Linux]]></title>
            <link>https://blog.devgenius.io/how-to-install-postgresql-using-terminal-on-ubuntu-linux-b0095ac8262?source=rss-236b66258bcb------2</link>
            <guid isPermaLink="false">https://medium.com/p/b0095ac8262</guid>
            <category><![CDATA[sql]]></category>
            <category><![CDATA[linux]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[beginners-guide]]></category>
            <category><![CDATA[postgresql]]></category>
            <dc:creator><![CDATA[Nnamani Ezinne Martina]]></dc:creator>
            <pubDate>Mon, 07 Aug 2023 14:59:42 GMT</pubDate>
            <atom:updated>2023-08-08T12:20:16.871Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="PostgreSQL icon" src="https://cdn-images-1.medium.com/max/600/1*jk5ExetrwM-G_XCiEgUTKQ.png" /><figcaption>Credit: <a href="https://freepngimg.com/png/">freepngimg.com</a></figcaption></figure><p>Introduction:</p><p>PostgreSQL, also known as Postgres, is a powerful and open-source object-relational database management system (ORDBMS). It offers advanced features, high scalability, and robust data integrity, making it a popular choice for various applications.</p><p>In this article, we will walk you through installing PostgreSQL on a Linux Ubuntu system. Whether you are a developer, a system administrator, or an enthusiast, this guide will help you get PostgreSQL up and running smoothly.</p><p>First, we make sure that the system is updated to the latest packages by running the following commands in the terminal:</p><pre>sudo apt update<br>sudo apt upgrade</pre><h4>Step 1: Installing PostgreSQL:</h4><p>To install PostgreSQL, we will use the apt package manager, which is the default package manager for Ubuntu. Open the terminal and execute the following command:</p><pre><br>sudo apt install postgresql postgresql-contrib</pre><p>This command will download and install the PostgreSQL packages along with the necessary dependencies.</p><p>It will also add a default PostgreSQL user — <strong><em>postgres</em></strong><em>.</em></p><h4>Step 2: Verifying the Installation:</h4><p>Once the installation is complete, PostgreSQL will automatically start running as a background service. <br>In the Ubuntu terminal, log in as a Postgres user with the following command:</p><pre>sudo -i -u postgres</pre><p>Running the command psql when logged in as a <em>Postgres</em> user will show the version of Postgres installed. This command will enable you to log into the PostgreSQL prompt, which allows you to interact with the database management system.</p><pre>psql</pre><p>To get more help from the command, you can use the --help command.</p><pre><br>psql --help</pre><h4>Step 3: Creating a New PostgreSQL user role (Optional)</h4><p>This is an optional step. The default Postgres user created when PostgreSQL was installed can be used without issues. You also have the flexibility of creating an additional user.</p><p>3a. In the terminal, log in as a Postgres user. Then run the command below:</p><pre>//Login as a Postgres user<br><br>sudo -i -u postgres<br><br><br>//Create a new user role<br>createuser --interactive</pre><p>Remember the name of the role added. We will need to add the database with the same name. Add the name of the role and accept the user to be a superuser. For the tutorial purpose, we will use the name o the user as <em>poweruser.</em></p><p>We will create a database for it and also a new user using the same name — <em>poweruser</em>.</p><p>3b. Create a database for the user</p><pre>createdb poweruser</pre><p>3c. Create a new Linux user that matches that of the database created in 3b above.</p><pre>sudo adduser poweruser</pre><p>3d. Open a new terminal and log in using the newly created user</p><pre>sudo -i -u poweruser</pre><p>3e. Test the installation on the Postgres user. Type <em>psql</em> after logging in as a user to connect to the database.</p><pre>psql</pre><p>Remember that step 3 is optional. One can easily log in using the default Postgres user.</p><h4>Congratulations! You have successfully installed PostgreSQL on your Ubuntu Linux system.</h4><p>To expand your knowledge of commands for creating and modifying databases and tables, you can explore the <a href="https://medium.com/@nnamani.ezinne/getting-started-with-sql-basics-834d2eeccb64">article</a>.</p><p>You can now utilize the power and flexibility of PostgreSQL to build robust and scalable database-driven applications.</p><p>Happy Coding =)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b0095ac8262" width="1" height="1" alt=""><hr><p><a href="https://blog.devgenius.io/how-to-install-postgresql-using-terminal-on-ubuntu-linux-b0095ac8262">How to install PostgreSQL using Terminal on Ubuntu Linux</a> was originally published in <a href="https://blog.devgenius.io/">Dev Genius</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>