<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Babacar Cisse DIA</title>
    <description>The latest articles on DEV Community by Babacar Cisse DIA (@bcdbuddy).</description>
    <link>https://dev.to/bcdbuddy</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%2F188119%2Fe5fb37cd-ab98-4745-a315-a61de223b3e7.jpeg</url>
      <title>DEV Community: Babacar Cisse DIA</title>
      <link>https://dev.to/bcdbuddy</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/bcdbuddy"/>
    <language>en</language>
    <item>
      <title>From Childhood Curiosity to Tech Leadership: Babacar's Journey and Insights for Aspiring Developers</title>
      <dc:creator>Babacar Cisse DIA</dc:creator>
      <pubDate>Mon, 30 Sep 2024 17:42:00 +0000</pubDate>
      <link>https://dev.to/bcdbuddy/from-childhood-curiosity-to-tech-leadership-babacars-journey-and-insights-for-aspiring-developers-n1m</link>
      <guid>https://dev.to/bcdbuddy/from-childhood-curiosity-to-tech-leadership-babacars-journey-and-insights-for-aspiring-developers-n1m</guid>
      <description>&lt;p&gt;Originally published on &lt;a href="https://bcd.dev/post/from-childhood-curiosity-to-tech-leadership-babacars-journey-and-insights-for-aspiring-developers-174" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Outline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Babacar's Story&lt;/li&gt;
&lt;li&gt;Choosing a Career&lt;/li&gt;
&lt;li&gt;Internships&lt;/li&gt;
&lt;li&gt;Early Projects&lt;/li&gt;
&lt;li&gt;Language&lt;/li&gt;
&lt;li&gt;Couchbase&lt;/li&gt;
&lt;li&gt;Laravel Couchbase&lt;/li&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;li&gt;Python&lt;/li&gt;
&lt;li&gt;[Pushing boundaries](#pushing-boundaries]&lt;/li&gt;
&lt;li&gt;Artificial Intelligence&lt;/li&gt;
&lt;li&gt;Large Language Models&lt;/li&gt;
&lt;li&gt;Limiting the scope&lt;/li&gt;
&lt;li&gt;Open Source vs Closed Source&lt;/li&gt;
&lt;li&gt;Couchbase SQL Plus&lt;/li&gt;
&lt;li&gt;Problem Focus&lt;/li&gt;
&lt;li&gt;Problem Solving and communication&lt;/li&gt;
&lt;li&gt;Pseudocode&lt;/li&gt;
&lt;li&gt;Empathy&lt;/li&gt;
&lt;li&gt;Ask Questions&lt;/li&gt;
&lt;li&gt;Learning Process&lt;/li&gt;
&lt;li&gt;Advice for Aspiring Developers&lt;/li&gt;
&lt;li&gt;Learning Languages&lt;/li&gt;
&lt;li&gt;Future Projects&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Photo by &lt;a rel="noopener noreferrer" href="https://unsplash.com/@oshomah?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Oshomah Abubakar&lt;/a&gt; on &lt;a rel="noopener noreferrer" href="https://unsplash.com/photos/shallow-focus-photography-of-boy-with-white-hat-80wYSpqSxX8?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Interview Transcript
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Babacar's Story
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Let's jump right in if that's okay with you. Sound good?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Sure, let's do it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Cool, love it! So my first question is, I always think it's really important for our community to learn more about your story. How did you get started in tech, and what was your journey like?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: For me, since I was a little kid, I always knew I wanted to work in tech. I was that kid always trying to open things up to see how they worked inside. You’d often find me with a screwdriver, laying all the pieces out and trying to figure out the "why" and "how" behind it all. Fast forward, I knew tech was my path, so I studied it in college. At first, it was hard to decide which area of tech to focus on, so I did something a bit unconventional: I figured out what I didn't want. I started crossing things off the list, and eventually, I realized software engineering was where I wanted to be.&lt;/p&gt;




&lt;h3&gt;
  
  
  Choosing a Career
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: How did you know what you wanted to focus on in tech? With it being such a vast space, how did you decide what wasn't for you?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Back in high school, there was this great website that had profiles for different professions. I’d look at what a typical day was like for each job and think, "No, I don’t like this environment or this kind of work." I kept crossing things off the list, and by the time I got to three options, I knew I wanted to pursue computer science.&lt;/p&gt;




&lt;h3&gt;
  
  
  Internships
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Amazing! So did you major in computer science in college?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Yes, I did computer science, then information systems, and finally software engineering.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Did you do any internships while you were still in school?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Yeah, I started working on projects during my second year of college. I also did something that might seem crazy: I’d open job boards and apply for positions where I met only one out of 20 qualifications. I figured, "Okay, let’s keep going," and learned as I went. Eventually, I’d meet more and more qualifications until someone hired me. You don’t need to have 10 out of 10 qualifications to get a job.&lt;/p&gt;




&lt;h3&gt;
  
  
  Early Projects
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: I know you’ve worked on some open-source projects. What’s one of the first projects you built that you loved, either because it was challenging or creative?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I try to build projects that solve my own problems first. One project I remember was a multiplayer game where we had trouble scaling the servers properly. The rooms couldn’t be too big or too small, and it was all new to me at the time. We eventually got it working, which felt amazing because we were under a lot of pressure from the customer.&lt;/p&gt;




&lt;h3&gt;
  
  
  Language
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: What language did you use for that game?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: The main application was in Laravel, with some parts in Node.js. It was a mix, but Laravel handled most of it.&lt;/p&gt;




&lt;h3&gt;
  
  
  Couchbase
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: How did you come across Couchbase, and what made you want to work with it?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: My first introduction was actually to CouchDB back in college. A professor had us research different databases, not just MySQL or PostgreSQL. Later, at work, the enterprise architect decided we needed a NoSQL solution, and Couchbase was proposed. We were already using Laravel, and Couchbase had an Eloquent driver that made it easy to integrate into the Laravel ecosystem.&lt;/p&gt;




&lt;h3&gt;
  
  
  Laravel Couchbase
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: What problem were you solving with Laravel Couchbase?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Laravel comes built-in with SQL database support, but Couchbase didn’t have official support. We found a five-year-old driver that hadn’t been updated, so we upgraded it to support the latest Laravel syntax and Couchbase versions. The goal was to keep it up-to-date and maintain it, even if we’re no longer using Couchbase ourselves.&lt;/p&gt;




&lt;h3&gt;
  
  
  PHP
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: So is PHP your go-to programming language?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I see languages as tools. It depends on the project. But for the last few years, yes, I’ve mainly worked with PHP and Laravel. That said, I also work with JavaScript and Python, though my Python is a bit rusty now.&lt;/p&gt;




&lt;h3&gt;
  
  
  Python
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I haven't worked with it for about two years, but when I was using it, Python was one of my favorite languages. Now, of course, I'm working with JavaScript. JavaScript allows you to make a lot of different mistakes—you can do almost anything with it. That’s one of the reasons I love TypeScript. The strict typing provides guardrails; it doesn’t let you create a variable that could be a string, a number, or anything else.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: I'm with you 100%, that's funny.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pushing boundaries
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt; As a developer, how do you push the boundaries and explore new technologies? Couchbase, for example, was something you didn’t know before, but then you realized it was an incredible technology to build off of. How do you stay up to date with the latest trends?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: To be honest, it’s not easy. There’s always something new coming around the corner. If you just follow the conversations, it might seem like everyone is using the latest trend, but in reality, most people are still running Java and PHP on their web servers. That said, I’m curious by nature, so I try to stay up to date—not 100%, but I keep an eye on things from a distance. I follow different runtimes, languages, and frameworks to see what people are building with them. Sometimes I find something interesting to work on or even join the trend.&lt;/p&gt;

&lt;p&gt;After work, I usually spend about an hour or less digging through social media or YouTube, letting the algorithms recommend content to me. I pick a couple of topics, create a study plan, and decide which ones I want to become proficient in. I also make sure to keep revisiting certain things to reflect on what I’ve learned, both for work and personal growth. Revisiting things helps me reassess my understanding over time.&lt;/p&gt;




&lt;h3&gt;
  
  
  Artificial Intelligence
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Are you diving into AI at all?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Yes, definitely. I’ve been exploring crypto and AI. I’m interested in the potential of AI but also cautious. Right now, I’m more focused on data science because you can do a lot with just that. Machine learning and AI are huge, but sometimes simpler solutions are all you need.&lt;/p&gt;




&lt;h3&gt;
  
  
  Large Language Models
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Have you worked with large language models (LLMs)?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I haven’t done a lot with LLMs yet. My idea is more about using smaller, focused models that do one thing really well rather than trying to have one giant model do everything.&lt;/p&gt;




&lt;h3&gt;
  
  
  Limiting the scope
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: I love that you’re thinking about limiting the scope a bit. You mentioned using a much smaller model that's very focused and does one thing really well, rather than relying on large language models (LLMs) that try to do everything. We often see LLMs generate hallucinations—things that just aren’t true. For example, they might provide a code sample that looks plausible, but as software engineers, we quickly realize it's wrong.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Exactly. There are definitely challenges with LLMs. What I’d like to see, as you mentioned, is AI used in a more tailored, specific way to repeatedly achieve a well-defined task. I think that’s a space we’re currently missing—a model that excels at one thing, rather than trying to create something that mimics the human mind and handles everything. Scoping AI down can lead to better results.&lt;br&gt;
It feels like every AI tutorial or blog post these days ends with a sales pitch. They’ll walk you through a basic setup, only to steer you towards signing up for a platform. Once you sign in, you're essentially locked in and can’t use anything else. That’s not AI—that’s just platform dependency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Exactly, and that’s a big difference. It's not true AI if you're just using someone’s platform. You're tied to that ecosystem.&lt;/p&gt;
&lt;h3&gt;
  
  
  Open Source vs Closed Source
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: How do companies and developers navigate the balance between open-source and closed-source platforms? For example, with OpenAI, when you're using ChatGPT, you're on their platform, and many are paying for that. But there are also open-source versions of AI, specifically LLMs. How can we build models based on open-source data and make them fully open, rather than locked into a closed-source system?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: That’s a good point, and it’s part of the process. I'm currently working on a series of &lt;a href="https://bcd.dev/post?tags[]=diy" rel="noopener noreferrer"&gt;"do it yourself"&lt;/a&gt; projects that focus on going back to basics. If you understand the fundamentals, you can navigate both old and new technologies, even those you’ve never encountered. For example, if you have a solid understanding of how databases work—whether relational or not—you can adapt quickly. That’s what I love about CQL. Coming from a relational database background, I didn’t feel lost when using it because it’s quite similar, just with its own syntax. This familiarity helped me speed up my workflow on that project.&lt;/p&gt;
&lt;h3&gt;
  
  
  Couchbase SQL Plus
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: That's perfect! You already know Couchbase has SQL Plus+, which is our version of SQL. It translates easily for people who already know SQL, and even for those unfamiliar with SQL, we have Capella IQ, an AI that teaches the syntax for creating queries within Couchbase SQL Plus. It equips users with all the skills they need to learn a new querying language, which is incredible. So, artificial intelligence can be used to educate and create platforms for learning, which is a huge long-term benefit.&lt;/p&gt;

&lt;p&gt;Many developers are still apprehensive about AI, which is understandable since it's new, but the conversation around it has been going on for years. Once people learn the tailored benefits and tools AI can offer, it's a massive win. I love that!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Absolutely. AI can do so much for education, especially in something like SQL Plus+, where people can quickly learn the language. It’s great to see platforms that not only provide the tech but help people learn to use it effectively.&lt;/p&gt;
&lt;h3&gt;
  
  
  Problem Focus
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: It’s great work. So thinking about our larger state as engineers and how technology is shaping the future, what roles do developers and engineers have in that transformation?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Right now, there’s almost nothing you can do without tech. I was just talking to someone in construction, and they have a massive IT department working internally. It doesn’t matter what field you're in—eventually, you'll need tech. Without it, you won’t stay relevant. The role of engineers is to ensure systems are working, tested thoroughly, and easy for people to navigate. Whether it's an API or a website, it’s ultimately for someone else to use, so empathy plays a big part. Technology evolves, but the theories behind it don’t.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Exactly. It's vital to ensure that technology is accessible, not just to tech elites but also to the general population. It’s about making it usable for everyone—from seniors who may be intimidated by technology to children growing up with it. It needs to be safe and accessible.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Absolutely. Developers should focus on applying technology to solve real-world problems. AI and data science are examples where you don't always need deep learning—sometimes, data science alone can get you there. It depends on the use case. I also like talking to people from different fields to see the problems they're facing and come up with solutions. It’s about applied technology, which is always more interesting than working with tech in a vacuum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Agreed. It's about problem-focused solutions, understanding preferences, and sometimes even controlling a market. Take Apple, for example, with their seamless ecosystem—it drives preferences.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Exactly. Cross-pollination is key.&lt;/p&gt;
&lt;h3&gt;
  
  
  Problem Solving and communication
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: How do you approach problem-solving in your development work?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I like to break things down into smaller steps. I start with an MVP (minimum viable product), and then iterate on it. It doesn’t have to be perfect at first, but through iteration, you get closer to the best solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: The importance of pseudocode cannot be overstated. I always recommend writing out your pseudocode first in plain language—whatever you speak to yourself in daily. Just write out the problem statement or what you want the code to achieve. Once you've laid out the entire problem, only then should you start creating functions or writing the actual code in JavaScript, TypeScript, Python, or whatever language you’re using. It helps to clarify the steps before diving into the actual code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: That's a great approach. When I’m working on something complex, I break it down into small, manageable steps and write everything out in plain text. No code, no algorithm at first—just an explanation that's easy to understand. Once the steps are clear, the algorithm and code follow naturally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Exactly! I think many developers forget the power of pseudocode. Writing out the logic before coding can save time and avoid confusion. Speaking of communication, engineers are often seen as bad communicators. How do you effectively communicate and collaborate with your teammates or clients?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I start with empathy. You need to be able to read people, especially since you may not share the same values or culture. Being able to understand where someone is coming from makes collaboration easier. We get a bad reputation for being poor communicators, but solving complex problems requires clear communication. Translating difficult concepts into something everyone can understand is crucial. Writing the code is the easy part; explaining the problem and the solution is the challenge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Absolutely. Communication is key, and it’s something we all need to work on continuously.&lt;/p&gt;


&lt;h3&gt;
  
  
  Pseudocode
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: The importance of pseudocode cannot be overstated. I always recommend writing out your pseudocode first in plain language—whatever you speak to yourself in daily. Just write out the problem statement or what you want the code to achieve. Once you've laid out the entire problem, only then should you start creating functions or writing the actual code in JavaScript, TypeScript, Python, or whatever language you’re using. It helps to clarify the steps before diving into the actual code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: That's a great approach. When I’m working on something complex, I break it down into small, manageable steps and write everything out in plain text. No code, no algorithm at first—just an explanation that's easy to understand. Once the steps are clear, the algorithm and code follow naturally.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Exactly! I think many developers forget the power of pseudocode. Writing out the logic before coding can save time and avoid confusion. Speaking of communication, engineers are often seen as bad communicators. How do you effectively communicate and collaborate with your teammates or clients?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I start with empathy. You need to be able to read people, especially since you may not share the same values or culture. Being able to understand where someone is coming from makes collaboration easier. We get a bad reputation for being poor communicators, but solving complex problems requires clear communication. Translating difficult concepts into something everyone can understand is crucial. Writing the code is the easy part; explaining the problem and the solution is the challenge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Absolutely. Communication is key, and it’s something we all need to work on continuously.&lt;/p&gt;


&lt;h3&gt;
  
  
  Empathy
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: You started by emphasizing empathy, and I think that’s absolutely key. Taking your ego out of conversations is essential. It’s not about pushing your own perspective or saying, "This is my code, so we must develop it this way." It’s about listening to the wants and needs of the team, the company, and the community.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Exactly. We often get into debates—like "I like React, you like Vue," and the conversation turns into a competition. But if something solves the problem, why argue? Empathy means being open to change and new ideas. Otherwise, you might find yourself sticking to one technology for the rest of your life without exploring new frameworks. It's about being flexible and open-minded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Yes, and that openness allows teams to work together towards a common mission. It’s not about personal preferences, but about achieving shared goals.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Absolutely. I might be naturally empathetic, but I always try to stay open—open your eyes, open your ears, ask questions, and never assume anything. That’s the key to effective collaboration and growth.&lt;/p&gt;


&lt;h3&gt;
  
  
  Ask Questions
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Yes, 100%. Asking questions is crucial, and yet so many of us are afraid to ask because we don’t want to feel dumb or uninformed, especially as we grow into more senior roles. People expect us to have all the answers, but being honest about what we don’t know is actually a powerful thing. Most senior engineers I talk to often say, "It depends." That’s a perfect answer because it’s true—you have to consider different factors for every problem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Exactly. Asking questions is a lifelong skill, especially in tech. You’ll always have to ask questions and keep learning, because no one knows everything. Even those with 25+ years of experience are still searching for answers. Tech is always evolving, and understanding that the learning process never ends is important.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Absolutely. Look at how coding used to be done on punch cards back in the day. The process and tools are vastly different now. The key is to stay curious, keep asking questions, and know that this process is ongoing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Ego has no place in this conversation, especially when working with a team. If I can’t convince someone that my way is the best way, maybe I’m wrong. It’s important to hear others out and reconsider your approach.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Exactly. That openness to feedback is what drives growth and collaboration.&lt;/p&gt;


&lt;h3&gt;
  
  
  Learning Process
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Like you mentioned, taking ego out of the equation and being willing to admit, "Maybe I’m wrong," is key. I’m always willing to step back and learn from others. Let's try it their way, and whether it works or not, it's okay. We're going through this process together as a team. At the end of the day, we’re a unified team—if we win, we win together; if we lose, we lose together.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Absolutely. Back when I was an engineer, we had the mentality of "we break production together." If code went to production and something went wrong, it wasn’t one person's fault—it was a team issue. We’d learn from it and grow together, and that’s the kind of collaborative environment that’s so crucial. I love that you’re cultivating that kind of space at Kirschbaum.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Exactly. It's all about learning and improving together. There’s always room to grow, and that process never stops.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Yes, and I’m glad you mentioned that willingness to keep learning. It’s not about knowing everything; it’s about continuously improving, and communication is a huge part of that. When engineers can communicate and collaborate effectively, the whole team grows.&lt;/p&gt;


&lt;h3&gt;
  
  
  Advice for Aspiring Developers
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: It's important to iterate on code, improve it, and not just stop after shipping the MVP. The willingness to come back, reassess, and have an honest conversation about the current state is crucial. That’s what we call managing tech debt—it’s about constantly improving, not just settling for "it works."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Exactly! That’s a great point. For junior developers, or those aspiring to get into the field, what advice would you give them?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I often tell aspiring developers to take it easy and go step by step. We didn’t learn everything overnight. No one starts with 10 years of experience. For example, we didn’t learn Laravel before learning PHP. First, we learned HTML and CSS, then PHP, and eventually JavaScript. After that, maybe Vue or React. You don’t need to force yourself to learn all these technologies in a few months, as many bootcamps might suggest.&lt;/p&gt;

&lt;p&gt;Take it one step at a time. You don’t need to be an expert in everything, but you should know enough to work with a technology. Once you find what you’re passionate about, dive deeper into that area. This approach applies not just to tech, but to learning in any field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: That’s so true! Learning progressively, building solid foundations, and going deeper into areas of interest is the best way to grow as a developer.&lt;/p&gt;


&lt;h3&gt;
  
  
  Learning Languages
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Yes, exactly! Take it slow. Don't feel like you have to learn six languages in two months. Be patient with yourself. Learning programming languages is similar to learning human languages—it’s a process. We didn’t become fluent in a language at two months old, right? It starts with simple sounds, and over time we grow, learn structure, and eventually master it. That’s the same approach we need for programming. It takes time, and that’s okay.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Absolutely. You need to stumble, make mistakes, and grow. Learning takes time, and being patient with yourself is key. It’s important to understand that it’s a gradual process and to be proud of each step forward.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: 100%! And what’s your favorite learning resource that you’ve used to master different languages?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Honestly, I’m still Googling to this day! I don’t have a specific resource because I like to change things up. I dive deep into subjects I’m interested in, then circle back and check what I may have missed. I like using different resources for different perspectives. For example, I’ll watch a Laravel series from one source, then watch a similar series from another to see how they explain it differently. Even watching beginner-level tutorials can give you that extra 1% of knowledge you missed before.&lt;/p&gt;

&lt;p&gt;What matters most is knowing how to use tools like Google effectively and how to ask the right questions. Once you break down problems into smaller, manageable chunks, it becomes much easier to build from there and work your way up to more complex issues.&lt;/p&gt;


&lt;h3&gt;
  
  
  Future Projects
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: One of the biggest challenges for new engineers is knowing how to ask the right questions. Sometimes, they don't even know how to begin asking. But that's part of the learning process—knowing how to use tools like Google to get answers and figuring out what to input to get the information you're looking for.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Exactly. It’s all about understanding how to ask the right questions. As for future projects, IoT (Internet of Things) is a big focus for me right now. For example, I recently spent two weeks installing a GPS on my bike, which was very different from just coding. I also bought an electronics kit to dive deeper into that side of things. IoT has been a side project for many years, and I’d love to dedicate more time to it. I’m even thinking about creating an intelligent field that handles tasks like watering soil based on sensor data, adjusting for sunlight, and changing angles based on the time of day or year.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: That sounds amazing! Any plans involving AI?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: Not at the moment. For me, it all depends on the use case. I don’t currently have a problem that AI can solve, but I’m always on the lookout. Aside from IoT, I’m also exploring different protocols—like RTSP, a protocol for resumable file uploads that I just recently discovered. It works over HTTP, and I’m interested in learning more about protocols beyond the usual FTP or SSH.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nyah&lt;/strong&gt;: Wow, I love how varied your interests are! Looking forward to seeing what you build.&lt;/p&gt;

&lt;p&gt;Where can people find you online if they want to follow your journey?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Babacar&lt;/strong&gt;: I’m active on Twitter as &lt;a href="https://twitter.com/babacarcissedia?ref=bcd.dev" rel="noopener noreferrer"&gt;@babacarcissedia&lt;/a&gt; and you can also check out my website at &lt;a href="https://kirscbaumdevelopment.com?ref=bcd.dev" rel="noopener noreferrer"&gt;Kirschbaum Development&lt;/a&gt;, where I document my projects and share resources.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/dzAAf2x4i78"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://bcd.dev/post/from-childhood-curiosity-to-tech-leadership-babacars-journey-and-insights-for-aspiring-developers-174" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>couchbase</category>
      <category>interview</category>
    </item>
    <item>
      <title>Setting Up Laravel on Your Own Server: A DIY Guide</title>
      <dc:creator>Babacar Cisse DIA</dc:creator>
      <pubDate>Mon, 30 Sep 2024 17:34:46 +0000</pubDate>
      <link>https://dev.to/bcdbuddy/setting-up-laravel-on-your-own-server-a-diy-guide-1i2b</link>
      <guid>https://dev.to/bcdbuddy/setting-up-laravel-on-your-own-server-a-diy-guide-1i2b</guid>
      <description>&lt;p&gt;Originally published on &lt;a href="https://bcd.dev/post/setting-up-laravel-on-your-own-server-a-diy-guide-131" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before you go through the pain and challenge of configuring your own server you should perhaps consider &lt;a href="https://forge.laravel.com" rel="noopener noreferrer"&gt;Laravel forge&lt;/a&gt;. I trust they would know better how to deploy a laravel app.&lt;/p&gt;

&lt;p&gt;For curious minded people, this is part of a bigger series &lt;a href="https://bcd.dev/post?tags.=diy" rel="noopener noreferrer"&gt;Do it yourself series&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Components
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;webserver

&lt;ul&gt;
&lt;li&gt;nginx&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;database

&lt;ul&gt;
&lt;li&gt;mysql&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;php&lt;/li&gt;

&lt;li&gt;composer&lt;/li&gt;

&lt;li&gt;node&lt;/li&gt;

&lt;li&gt;npm / yarn&lt;/li&gt;

&lt;li&gt;scheduler&lt;/li&gt;

&lt;li&gt;firewall&lt;/li&gt;

&lt;li&gt;log

&lt;ul&gt;
&lt;li&gt;papertrail&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;search

&lt;ul&gt;
&lt;li&gt;elastic search&lt;/li&gt;
&lt;li&gt;algolia&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;other third party services

&lt;ul&gt;
&lt;li&gt;redis&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Basic build
&lt;/h2&gt;

&lt;p&gt;recepee on an ubuntu server (22-10)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;mysql&lt;/li&gt;
&lt;li&gt;php&lt;/li&gt;
&lt;li&gt;composer&lt;/li&gt;
&lt;li&gt;node&lt;/li&gt;
&lt;li&gt;nginx&lt;/li&gt;
&lt;li&gt;queue&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Requirements
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;VPS Server&lt;/li&gt;
&lt;li&gt;Valid DNS record pointing to your server&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Mysql
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; mysql-server

&lt;span class="c"&gt;# Init project by creating a user with a dedicated database&lt;/span&gt;
&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;root_username&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;4&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s1"&gt;'root'&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;root_password&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;5&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; tmp.sql
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"CREATE USER &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;@localhost identified by &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="nv"&gt;$password&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; tmp.sql
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"CREATE DATABASE &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt; charset utf8 collate utf8_general_ci;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; tmp.sql
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"GRANT ALL PRIVILEGES ON &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;.* to &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;@localhost;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; tmp.sql
mysql &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="nv"&gt;$root_username&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="nv"&gt;$root_password&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"source tmp.sql"&lt;/span&gt;


mysql &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="nv"&gt;$root_username&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="nv"&gt;$root_password&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"CREATE DATABASE &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt; charset utf8 collate utf8_general_ci;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Php
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; software-properties-common
&lt;span class="nb"&gt;sudo &lt;/span&gt;add-apt-repository ppa:ondrej/php
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt update

&lt;span class="c"&gt;# php with some extensions&lt;/span&gt;
&lt;span class="nv"&gt;PHP_VERSION&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s1"&gt;'8.2'&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; &lt;span class="s2"&gt;"php&lt;/span&gt;&lt;span class="nv"&gt;$PHP_VERSION&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; php&lt;span class="nv"&gt;$PHP_VERSION&lt;/span&gt;-&lt;span class="o"&gt;{&lt;/span&gt;common,cli,fpm,zip,xml,pdo,mysql,mbstring,tokenizer,ctype,curl,common,curl,gd,intl,sqlite3,xmlrpc,xsl,soap,opcache,readline,xdebug,bcmath&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Composer
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"copy('https://getcomposer.org/installer', 'composer-setup.php');"&lt;/span&gt;

&lt;span class="c"&gt;# For simplicity purpose, we are skipping the hash check. That is a crucial step you wouldn't want to skip when downloading stuff on the internet&lt;/span&gt;
&lt;span class="c"&gt;# Hash below matches composer version 2.1.3&lt;/span&gt;
&lt;span class="c"&gt;# php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"&lt;/span&gt;
php composer-setup.php
php &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"unlink('composer-setup.php');"&lt;/span&gt;
&lt;span class="nb"&gt;sudo mv &lt;/span&gt;composer.phar /usr/local/bin/composer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Node
&lt;/h3&gt;

&lt;p&gt;You can get node on their website but I prefer getting specific version from node version manager (nvm)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;1&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s1"&gt;'20'&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Installing nvm + node &lt;/span&gt;&lt;span class="nv"&gt;$version&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
wget &lt;span class="nt"&gt;-qO-&lt;/span&gt; https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
&lt;span class="nb"&gt;source&lt;/span&gt; ~/.bashrc
nvm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nv"&gt;$version&lt;/span&gt;
&lt;span class="c"&gt;# Optional but I like yarn so here we go&lt;/span&gt;
nvm &lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nv"&gt;$version&lt;/span&gt; npm i yarn &lt;span class="nt"&gt;-g&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Nginx
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Making sure apache is not installed to avoid conflict on port 80&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get remove &lt;span class="nt"&gt;-y&lt;/span&gt; apache
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; nginx
&lt;span class="nb"&gt;rm&lt;/span&gt; /etc/nginx/sites-available/default  /etc/nginx/sites-enabled/default 

&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt; &lt;span class="c"&gt;# site.domain&lt;/span&gt;
&lt;span class="nv"&gt;webroot&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"/var/www/vhosts/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nv"&gt;$webroot&lt;/span&gt;
&lt;span class="nb"&gt;touch&lt;/span&gt; &lt;span class="s2"&gt;"/etc/nginx/sites-available/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;.conf"&lt;/span&gt;
&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"/etc/nginx/sites-available/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;.conf"&lt;/span&gt; &lt;span class="s2"&gt;"/etc/nginx/sites-enabled/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;.conf"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"/etc/nginx/sites-available/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;.conf"&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    root &lt;/span&gt;&lt;span class="nv"&gt;$webroot&lt;/span&gt;&lt;span class="sh"&gt;;
    server_name &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt; www.&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt;;
}
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Secure traffic using HTTPS
&lt;/h4&gt;

&lt;p&gt;At this point we are running a web server on port 80. However everyone can see the content flowing through the networking. Welcome https.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;domain&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;2&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"your@email.com"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; python3-certbot-nginx


&lt;span class="c"&gt;# manual&lt;/span&gt;
&lt;span class="c"&gt;# certbot certonly -a manual --rsa-key-size 4096 --email $email -d $domain -d www.$domain&lt;/span&gt;

&lt;span class="c"&gt;# auto&lt;/span&gt;
&lt;span class="c"&gt;## With base nginx config&lt;/span&gt;
certbot certonly &lt;span class="nt"&gt;--nginx&lt;/span&gt; &lt;span class="nt"&gt;--rsa-key-size&lt;/span&gt; 4096 &lt;span class="nt"&gt;--email&lt;/span&gt; &lt;span class="nv"&gt;$email&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nv"&gt;$domain&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; www.&lt;span class="nv"&gt;$domain&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When the steps above succeed you can carry on with nginx config for ssl. The following will redirect all non secure connection (80) to secure connection (443)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Usage ./laravel.sh site.domain 8.2 ~/sites&lt;/span&gt;
&lt;span class="c"&gt;## Dependencies: letsencrypt, php$php_version, php$php_version-fpm&lt;/span&gt;

&lt;span class="c"&gt;# sudo apt-get install -y php$php_version php$php_version-fpm&lt;/span&gt;
&lt;span class="nv"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt; &lt;span class="c"&gt;# site.domain&lt;/span&gt;
&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$2&lt;/span&gt;
&lt;span class="nv"&gt;php_version&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;3&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s1"&gt;'8.2'&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;root&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;4&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"/var/www/vhosts/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;webroot&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;5&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="s2"&gt;"/var/www/vhosts/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="s2"&gt;/public"&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;touch&lt;/span&gt; /etc/nginx/sites-available/&lt;span class="nv"&gt;$name&lt;/span&gt;.conf
&lt;span class="nb"&gt;ln&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; /etc/nginx/sites-available/&lt;span class="nv"&gt;$name&lt;/span&gt;.conf /etc/nginx/sites-enabled/&lt;span class="nv"&gt;$name&lt;/span&gt;.conf

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/www/vhosts/&lt;span class="nv"&gt;$name&lt;/span&gt;/storage/logs
&lt;span class="nb"&gt;touch&lt;/span&gt; /var/www/vhosts/&lt;span class="nv"&gt;$name&lt;/span&gt;/storage/logs/error.log
&lt;span class="nb"&gt;touch&lt;/span&gt; /var/www/vhosts/&lt;span class="nv"&gt;$name&lt;/span&gt;/storage/logs/access.log

&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/nginx/sites-available/&lt;span class="nv"&gt;$name&lt;/span&gt;.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;

# Force HTTPS
server {
  listen 80;
  listen [::]:80;
  server_name &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt; www.&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt;;
  return 301 https://&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;request_uri;
}

# Force www less version'
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt;;
    ssl_certificate /etc/letsencrypt/live/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt;/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt;/privkey.pem;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    return 301 https://&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;request_uri;
}


server {
    server_name &lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt;;

    # SSL config
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_tokens off;
    ssl_buffer_size 8k;
    ssl_protocols TLSv1.3 TLSv1.2;
    ssl_prefer_server_ciphers on;
    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5;
    ssl_ecdh_curve secp384r1;
    ssl_session_tickets off;

    # OCSP stapling
    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 8.8.8.8 8.8.4.4;

    ssl_certificate /etc/letsencrypt/live/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt;/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/&lt;/span&gt;&lt;span class="nv"&gt;$name&lt;/span&gt;&lt;span class="sh"&gt;/privkey.pem;
    ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
    # End of SSL config


    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header X-XSS-Protection "1; mode=block";

    charset utf-8;

    index index.php index.html;
    error_log &lt;/span&gt;&lt;span class="nv"&gt;$root&lt;/span&gt;&lt;span class="sh"&gt;/storage/logs/error.log;
    access_log &lt;/span&gt;&lt;span class="nv"&gt;$root&lt;/span&gt;&lt;span class="sh"&gt;/storage/logs/access.log;
    root &lt;/span&gt;&lt;span class="nv"&gt;$webroot&lt;/span&gt;&lt;span class="sh"&gt;;
    error_page 404 /index.php;


    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";


    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    location / {
        try_files &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;uri &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;uri/ /index.php?&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;query_string;
        gzip_static on;

        proxy_set_header        Host &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;server_name;
        proxy_set_header        X-Real-IP &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;remote_addr;
        proxy_set_header        X-Forwarded-For &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;proxy_add_x_forwarded_for;
        proxy_set_header        X-Forwarded-Proto &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;scheme;
    }

    location ~ &lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;php&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="sh"&gt;{
        try_files &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;uri /index.php =404;
        fastcgi_split_path_info ^(.+&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;php)(/.+)&lt;/span&gt;&lt;span class="nv"&gt;$;&lt;/span&gt;&lt;span class="sh"&gt;
        fastcgi_pass unix:/run/php/php&lt;/span&gt;&lt;span class="nv"&gt;$php_version&lt;/span&gt;&lt;span class="sh"&gt;-fpm.sock;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;document_root&lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;fastcgi_script_name;
        fastcgi_param PATH_INFO &lt;/span&gt;&lt;span class="se"&gt;\$&lt;/span&gt;&lt;span class="sh"&gt;fastcgi_path_info;

        fastcgi_buffers 8 64k;
        fastcgi_buffer_size 128k;
        fastcgi_connect_timeout 3000;
        fastcgi_send_timeout 3000;
        fastcgi_read_timeout 3000;
    }

    location ~ /&lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;(?!well-known).* {
        deny all;
    }

    # Define caching rules for static images
    location ~* &lt;/span&gt;&lt;span class="se"&gt;\.&lt;/span&gt;&lt;span class="sh"&gt;(jpg|jpeg|png|gif|ico)&lt;/span&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="sh"&gt;{
        expires 30d; # adjust the caching duration as needed
        add_header Cache-Control "public, max-age=2592000";
    }

    gzip on;
    gzip_types text/plain text/css application/javascript image/*;

    client_max_body_size 128m;
    # For unlimited
    # client_max_body_size 0;
}
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# permissions&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;find storage &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;chmod &lt;/span&gt;664 &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;find storage &lt;span class="nt"&gt;-type&lt;/span&gt; d &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;chmod &lt;/span&gt;775 &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt;
&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; ug+rwx storage bootstrap/cache
&lt;span class="nb"&gt;sudo chgrp&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; www-data storage bootstrap/cache
&lt;span class="nb"&gt;sudo &lt;/span&gt;usermod &lt;span class="nt"&gt;-aG&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt; www-data
&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nv"&gt;$user&lt;/span&gt;:www-data &lt;span class="nt"&gt;-R&lt;/span&gt; storage bootstrap/cache

&lt;span class="c"&gt;# Check file exists&lt;/span&gt;
&lt;span class="c"&gt;# /etc/ssl/dhparams.pem&lt;/span&gt;
&lt;span class="c"&gt;# Generate if not&lt;/span&gt;
&lt;span class="c"&gt;# openssl dhparam -out /etc/ssl/dhparams.pem 4096&lt;/span&gt;


&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/php/&lt;span class="nv"&gt;$php_version&lt;/span&gt;/cli/php.ini &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
post_max_size=128M
upload_max_filesize=128M
max_upload_file=50
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h5&gt;
  
  
  Auto renew certificate
&lt;/h5&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# DISCLAIMER: it is safer to edit cron file using crontab dedicated command&lt;/span&gt;
&lt;span class="c"&gt;# That being see given this is a script we likely want to have automated&lt;/span&gt;
/var/spool/cron/crontabs

&lt;span class="c"&gt;## cron job to auto renew every 3 months for you&lt;/span&gt;
crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;span class="c"&gt;# 0 0 1 */3 * /usr/bin/certbot renew --quiet&lt;/span&gt;

&lt;span class="c"&gt;## I saw people doing it monthly&lt;/span&gt;
&lt;span class="c"&gt;# 0 0 1 * *&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Queue
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#! /bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;0&lt;/span&gt;&lt;span class="k"&gt;:-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;USER&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;
&lt;span class="nv"&gt;root_dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/home/&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="s2"&gt;/www/"&lt;/span&gt;
&lt;span class="nv"&gt;processes&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;4
&lt;span class="nb"&gt;sudo &lt;/span&gt;apt get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; supervisor
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/supervisor/conf.d/laravel-worker.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
process_name=%(program_name)s_%(process_num)02d
command=php &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;root_dir&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;/artisan queue:work --sleep=3 --tries=3 --max-time=3600
autostart=true
autorestart=true
stopasgroup=true
killasgroup=true
user=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;
numprocs=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;processes&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;
redirect_stderr=true
stdout_logfile=&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;root_dir&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;/storage/logs/worker.log
stopwaitsecs=3600
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl reread
&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl update
&lt;span class="nb"&gt;sudo &lt;/span&gt;supervisorctl start all

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

&lt;/div&gt;



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

&lt;p&gt;No conclusion as this is a starting point only but gets you an operational laravel app.&lt;br&gt;
Made a lot of arbitrary choices. Adapt for your usecase.&lt;br&gt;
Next up&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;automate script using orchestration (ie ansible)&lt;/li&gt;
&lt;li&gt;deploy using aws code deploy&lt;/li&gt;
&lt;li&gt;CI / CD pipeline from github&lt;/li&gt;
&lt;li&gt;tighting security with firewall policies&lt;/li&gt;
&lt;li&gt;monitoring&lt;/li&gt;
&lt;li&gt;load management / balancing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally published on &lt;a href="https://bcd.dev/post/setting-up-laravel-on-your-own-server-a-diy-guide-131" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>devops</category>
      <category>development</category>
    </item>
    <item>
      <title>Would you rather be a "Jack-of-all-trades" or "Master-of-one"? Why?</title>
      <dc:creator>Babacar Cisse DIA</dc:creator>
      <pubDate>Mon, 30 Sep 2024 17:29:00 +0000</pubDate>
      <link>https://dev.to/bcdbuddy/would-you-rather-be-a-jack-of-all-trades-or-master-of-one-why-14hi</link>
      <guid>https://dev.to/bcdbuddy/would-you-rather-be-a-jack-of-all-trades-or-master-of-one-why-14hi</guid>
      <description>&lt;p&gt;Originally published on &lt;a href="https://bcd.dev/post/would-you-rather-be-a-jack-of-all-trades-or-master-of-one-why-127" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Short answer: Master of one.&lt;/p&gt;

&lt;p&gt;As for many things my more elaborate answer would be it depends.&lt;/p&gt;

&lt;p&gt;It is valuable to be a Jack of all trades when working with a team. Your proficiency in many areas lifts up communication barrier, reducing the knowledge lost when translating terms.&lt;/p&gt;

&lt;p&gt;If I had to pick one I would go with Master of one. The reasoning behind is simple: Would you go to eye doctor for laser chirurgie or a generalist ?! My guess is you are going with the expert&lt;/p&gt;

</description>
      <category>expertise</category>
      <category>teamwork</category>
    </item>
    <item>
      <title>Living vs. Surviving: How to Stop Going Through the Motions and Start Thriving</title>
      <dc:creator>Babacar Cisse DIA</dc:creator>
      <pubDate>Mon, 30 Sep 2024 17:26:17 +0000</pubDate>
      <link>https://dev.to/bcdbuddy/living-vs-surviving-how-to-stop-going-through-the-motions-and-start-thriving-458l</link>
      <guid>https://dev.to/bcdbuddy/living-vs-surviving-how-to-stop-going-through-the-motions-and-start-thriving-458l</guid>
      <description>&lt;p&gt;Originally published on &lt;a href="https://bcd.dev/post/living-vs-surviving-how-to-stop-going-through-the-motions-and-start-thriving-29" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Outline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Are You Living or Surviving?&lt;/li&gt;
&lt;li&gt;The Rat Race: Fighting an Unwinnable War&lt;/li&gt;
&lt;li&gt;Understanding Business, Understanding Life&lt;/li&gt;
&lt;li&gt;The Best Time to Be Alive&lt;/li&gt;
&lt;li&gt;Abundance in Every Area&lt;/li&gt;
&lt;li&gt;What Do You Really Want?&lt;/li&gt;
&lt;li&gt;Aligning Actions with Goals&lt;/li&gt;
&lt;li&gt;Actions Speak Louder Than Words&lt;/li&gt;
&lt;li&gt;The Softness of Modern Society&lt;/li&gt;
&lt;li&gt;Hard Times vs. Easy Times&lt;/li&gt;
&lt;li&gt;Stop Making Excuses&lt;/li&gt;
&lt;li&gt;Take Ownership of Your Life&lt;/li&gt;
&lt;li&gt;Human Potential: Tapping into What We’re Capable Of&lt;/li&gt;
&lt;li&gt;Are You Fleeing from Reality?&lt;/li&gt;
&lt;li&gt;Finding Peace and Gratitude&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Photo by &lt;a rel="nofollow noindex noopener noreferrer" href="https://unsplash.com/@dankapeter?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Danka &amp;amp; Peter&lt;/a&gt; on &lt;a rel="nofollow noindex noopener noreferrer" href="https://unsplash.com/photos/man-wearing-black-shirt-and-gray-shorts-on-mountain-hill-beside-mountains-under-white-and-blue-cloudy-skies-L0o1RfQuPUY?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Are You Living or Surviving?
&lt;/h2&gt;

&lt;p&gt;In today’s fast-paced world, many of us are simply going through the motions. We wake up, work, check off the tasks on our to-do lists, and repeat the cycle the next day. But is this truly living, or are we just surviving? Living means engaging with life fully, embracing purpose and joy, while survival is a bare minimum state where we’re just trying to get by.&lt;/p&gt;

&lt;p&gt;The difference between the two may seem subtle, but it has a profound impact on our well-being and fulfillment. Many of us, unknowingly, are stuck in the &lt;strong&gt;rat race&lt;/strong&gt;, striving to reach arbitrary goals without stopping to reflect on whether we’re truly living. The good news is that making the shift from surviving to thriving is entirely possible, and it begins with awareness and intentionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Rat Race: Fighting an Unwinnable War
&lt;/h2&gt;

&lt;p&gt;The rat race is a term used to describe the never-ending cycle of working, competing, and chasing success, often without fulfillment. In this battle, there is no true winner. We’re constantly chasing the next goal—whether it’s more money, status, or approval—but when we reach it, we immediately look for the next target. It’s a constant grind, a cycle of living to see the next day without experiencing the fullness of life.&lt;/p&gt;

&lt;p&gt;In this state, we become disconnected from our purpose and what truly matters. Every day feels like a battle without a winner. The irony is, many of us don’t even stop to ask ourselves why we’re in this race to begin with. The lack of reflection and self-awareness keeps us stuck, running on a hamster wheel that never leads anywhere fulfilling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Business, Understanding Life
&lt;/h2&gt;

&lt;p&gt;Interestingly, the more we understand business, the more we can understand life itself. Business is often about strategy, growth, and resource management, which can also apply to how we live our lives. In both areas, the key to success is having clear goals, focusing on what matters, and avoiding distractions. Just as businesses set objectives and take action to achieve them, we must do the same in our personal lives.&lt;/p&gt;

&lt;p&gt;The trick is recognizing that life, like business, requires a vision and a plan. Without these, we’re just moving from one task to another, checking off boxes without feeling truly accomplished. Success in life, much like in business, comes from a balance of planning, effort, and reflection.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Best Time to Be Alive
&lt;/h2&gt;

&lt;p&gt;It’s easy to feel overwhelmed by the challenges of modern life. However, the reality is that we are living in one of the best times in history. &lt;strong&gt;Abundance&lt;/strong&gt; is everywhere. We have access to food, shelter, air conditioning, heating, knowledge, safety, and peace—things that were luxuries not so long ago. Yet, with all this abundance, why do so many of us feel like we’re just surviving?&lt;/p&gt;

&lt;h2&gt;
  
  
  Abundance in Every Area
&lt;/h2&gt;

&lt;p&gt;It’s important to acknowledge that we live in a time of unprecedented abundance. Everything from basic needs like food and shelter to luxuries like knowledge and safety is more accessible than ever before. But this abundance has created a paradox: the easier life becomes, the more we fall into complacency. We become soft, comfortable, and less driven to seek more meaningful goals.&lt;/p&gt;

&lt;p&gt;While having access to everything we need is a privilege, it’s also a challenge. When life is too comfortable, we lose the drive to push ourselves. We settle for mediocrity instead of striving for excellence. This is why, despite the abundance around us, many of us feel unfulfilled—we’re not challenging ourselves enough, and we’re not living with purpose.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Do You Really Want?
&lt;/h2&gt;

&lt;p&gt;It’s time to ask yourself the tough question: What do you truly want? This isn’t a superficial question about material desires; it’s about your deeper life goals. What do you want from life? What do you want for yourself today? What’s stopping you from achieving it right now?&lt;/p&gt;

&lt;h3&gt;
  
  
  Aligning Actions with Goals
&lt;/h3&gt;

&lt;p&gt;If you find yourself constantly saying you want something but not taking the necessary steps to achieve it, it’s time to reevaluate. Are your daily actions aligned with your goals? If not, you might need to reconsider whether you truly want what you say you do. Real desire is reflected in action. If you’re not taking steps toward your goals, you don’t want them as much as you think.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actions Speak Louder Than Words
&lt;/h3&gt;

&lt;p&gt;Words are easy, but actions are what truly matter. It’s simple to say that you want to improve your life, get a promotion, or achieve a certain goal. But without action, those words mean nothing. Everything you want is out there for you to take, but it’s not free. It requires your time, your energy, or your money—and sometimes all three.&lt;/p&gt;

&lt;p&gt;The truth is that what you do matters far more than what you say. It’s not enough to declare your intentions; you need to work toward them consistently. Whether it’s waking up earlier, investing in yourself, or learning new skills, every action you take gets you one step closer to your goals.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Softness of Modern Society
&lt;/h2&gt;

&lt;p&gt;Today’s society is often characterized by comfort and convenience, but that comfort can make us soft. People want the rewards without putting in the work. Everyone wants the fruits of labor, but few are willing to till the soil. &lt;strong&gt;Abundance&lt;/strong&gt; has created a generation of people who are quick to complain, slow to act, and often unprepared for the challenges of life.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hard Times vs. Easy Times
&lt;/h3&gt;

&lt;p&gt;There’s a saying: “Hard times create strong people, and easy times create weak people.” This reflects the idea that when life is too easy, people become complacent and lose the drive to work hard. The more abundant our surroundings, the less motivated we are to push ourselves beyond our comfort zones.&lt;/p&gt;

&lt;p&gt;In easy times, we become weaker—not physically, but mentally and emotionally. We lose the resilience that comes from overcoming obstacles, and we settle for a life that is easy but unfulfilling. The solution? Challenge yourself. Push beyond the comfort of everyday life, and seek out opportunities for growth and improvement.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop Making Excuses
&lt;/h2&gt;

&lt;p&gt;At the core of transitioning from survival to thriving is personal accountability. Too often, we make excuses for why we’re not where we want to be. We blame external factors—our job, the economy, or our circumstances—but rarely do we look inward and take responsibility for our choices.&lt;/p&gt;

&lt;h2&gt;
  
  
  Human Potential: Tapping into What We’re Capable Of
&lt;/h2&gt;

&lt;p&gt;As a species, we are brimming with untapped potential. The human capacity for innovation, growth, and improvement is astounding, yet many of us fail to reach our fullest abilities. The reason? Often, it’s not a lack of opportunity but rather a lack of vision or motivation. As long as you’re committed to improving, and as long as you can clearly envision what you want to achieve, the potential is limitless.&lt;/p&gt;

&lt;p&gt;But why do so many of us fall short? Some choose to stay in their comfort zones, doing only what’s required, like “working their wage” without striving for more. Others feel they don’t owe it to themselves or the world to push beyond the bare minimum. This mindset is one of self-limitation, and it keeps us from realizing just how much we’re capable of.&lt;/p&gt;

&lt;p&gt;The key to unlocking your potential is self-awareness and determination. The world is full of opportunities, but it’s up to you to seize them. It starts with a clear vision and a commitment to taking action.&lt;/p&gt;

&lt;h2&gt;
  
  
  Are You Fleeing from Reality?
&lt;/h2&gt;

&lt;p&gt;Many people, instead of confronting life’s challenges head-on, find ways to escape or distract themselves. This can come in various forms—avoiding difficult conversations, procrastinating, or even numbing feelings with distractions. But the question is: are you truly at peace with yourself? &lt;/p&gt;

&lt;p&gt;Being at peace means facing reality, accepting your flaws, and loving yourself regardless of external circumstances. It means being grateful for the blessings you have, rather than constantly focusing on what’s missing. The truth is, most of us have far more than we realize, yet we tend to fixate on the finite list of problems.&lt;/p&gt;

&lt;p&gt;If you can cultivate a mindset of gratitude, self-love, and peace, you’ll start to see life differently. The obstacles may remain, but your perspective will shift. You’ll recognize the blessings that surround you and understand that, while problems are inevitable, they are far fewer than the endless list of things you should be thankful for.&lt;/p&gt;

&lt;h2&gt;
  
  
  Take Ownership of Your Life
&lt;/h2&gt;

&lt;p&gt;It’s time to stop making excuses and start taking ownership of your life. If you’re not where you want to be, ask yourself why. Are you truly doing everything in your power to achieve your goals, or are you looking for reasons why you can’t succeed?&lt;/p&gt;

&lt;p&gt;Stop waiting for a hero to save you, stop sitting around hoping for a miracle, and stop waiting for the perfect moment to act. The perfect moment doesn’t exist. Success doesn’t come from waiting; it comes from doing. The world will keep spinning with or without you, and the sun will continue to rise and set each day. So why wait? If you want to change your life, you need to start taking action today.&lt;/p&gt;

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

&lt;p&gt;From surviving to truly living, the key is intentionality. Life offers more potential, abundance, and opportunities than we often realize, but it’s up to us to harness them. Whether it’s aligning your actions with your goals, taking ownership of your life, or tapping into your true potential, the power to change your circumstances lies within you. Stop fleeing from reality and embrace it. Be grateful for the blessings you have, and make peace with yourself. The best time to start thriving is now.&lt;/p&gt;

&lt;p&gt;Originally published on &lt;a href="https://bcd.dev/post/living-vs-surviving-how-to-stop-going-through-the-motions-and-start-thriving-29" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>personalgrowth</category>
      <category>selfawareness</category>
      <category>lifepurpose</category>
      <category>accountability</category>
    </item>
    <item>
      <title>Optimizing Sorting and Filtering on JSON Columns in Laravel with Indexed Virtual Columns</title>
      <dc:creator>Babacar Cisse DIA</dc:creator>
      <pubDate>Wed, 25 Sep 2024 16:51:20 +0000</pubDate>
      <link>https://dev.to/bcdbuddy/optimizing-sorting-and-filtering-on-json-columns-in-laravel-with-indexed-virtual-columns-1gnl</link>
      <guid>https://dev.to/bcdbuddy/optimizing-sorting-and-filtering-on-json-columns-in-laravel-with-indexed-virtual-columns-1gnl</guid>
      <description>&lt;p&gt;Originally posted on &lt;a href="https://bcd.dev/post/optimizing-sorting-and-filtering-on-json-columns-in-laravel-with-indexed-virtual-columns-165" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Outline
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
JSON Column Performance Challenges

&lt;ul&gt;
&lt;li&gt;Monitoring and Execution Time Issues&lt;/li&gt;
&lt;li&gt;Sorting and Filtering with JSON Columns&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Introducing Virtual Columns

&lt;ul&gt;
&lt;li&gt;Why Virtual Columns Work Better&lt;/li&gt;
&lt;li&gt;How to Implement Virtual Columns&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Benchmarking the Results

&lt;ul&gt;
&lt;li&gt;Before: Nested JSON Columns&lt;/li&gt;
&lt;li&gt;After: Virtual Column + Index&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;How to Optimize JSON Queries with Virtual Columns&lt;/li&gt;

&lt;li&gt;Conclusion and Best Practices&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  JSON Column Performance Challenges
&lt;/h2&gt;

&lt;p&gt;Working with large datasets stored in JSON columns presents significant performance issues, especially when filtering and sorting. In my experience, these challenges became evident while monitoring PHP processes and managing large volumes of records, leading to execution time limits being hit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring and Execution Time Issues
&lt;/h3&gt;

&lt;p&gt;As part of my regular monitoring duties, I encountered max execution times of 30 seconds while querying JSON columns in a 580k record dataset. JSON columns, though flexible, are prone to performance bottlenecks, particularly without proper indexing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sorting and Filtering with JSON Columns
&lt;/h3&gt;

&lt;p&gt;The first major issue appeared when working on a Filament list record page, which had default sorting applied to a JSON attribute. The absence of indexing on this attribute resulted in a significant slowdown, especially when processing over 10,000 records. Without an index, querying and sorting through nested JSON attributes can cause execution delays and inefficiencies in retrieving results, pushing PHP processes beyond acceptable limits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing Virtual Columns
&lt;/h2&gt;

&lt;p&gt;When faced with performance issues from sorting and filtering large JSON columns, I revisited an old solution: &lt;a href="https://kirschbaumdevelopment.com/insights/leveraging-virtual-generated-columns" rel="noopener noreferrer"&gt;virtual columns&lt;/a&gt; from my friend &lt;a href="https://twitter.com/therobfonz" rel="noopener noreferrer"&gt;Rob Fonseca&lt;/a&gt;. Virtual columns in MySQL allow me to create an indexed, computed column from JSON data, making queries more efficient without duplicating data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Virtual Columns Work Better
&lt;/h3&gt;

&lt;p&gt;Unlike standard JSON columns, virtual columns are calculated automatically from existing data but can be indexed, making them faster for querying. This improves sorting and filtering performance significantly, especially in large datasets where execution time is critical.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to Implement Virtual Columns
&lt;/h3&gt;

&lt;p&gt;I implemented virtual columns by adding a migration that created a new indexed column for filtering and sorting. This virtual column extracted and indexed specific JSON attributes, drastically improving query performance. Here's an example migration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;virtualAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"json_unquote(json_extract(data, '$.latest_approval_date'))"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By indexing this virtual column, I was able to reduce query times and improve overall efficiency, especially when filtering and sorting large datasets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benchmarking the Results
&lt;/h2&gt;

&lt;p&gt;Once I implemented the virtual columns, I needed to ensure the performance gains were real. Benchmarking provided concrete data, comparing the execution times of filtering, sorting, and paginating large datasets using both the original nested JSON column and the new virtual column with indexing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Before: Nested JSON Columns
&lt;/h3&gt;

&lt;p&gt;With over 580k records, queries on the nested JSON column were slow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sorting a page of 100 records took over 5,000ms.&lt;/li&gt;
&lt;li&gt;Filtering + sorting + paginating took nearly 2,000ms.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Benchmark&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;dd&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'count'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="s1"&gt;'paginate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'filter + paginate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'data-&amp;gt;latest_approval_date'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-09-05'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'sort + paginate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'data-&amp;gt;latest_approval_date'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'filter + sort + paginate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'data-&amp;gt;latest_approval_date'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-09-05'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'data-&amp;gt;latest_approval_date'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  After: Virtual Column + Index
&lt;/h3&gt;

&lt;p&gt;After indexing the virtual column, the improvements were substantial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sorting the same page of 100 records dropped to 750ms (&lt;strong&gt;7.5x faster&lt;/strong&gt;).&lt;/li&gt;
&lt;li&gt;Filtering + sorting + paginating improved to just 53ms (&lt;strong&gt;36x faster&lt;/strong&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These benchmarks confirmed the effectiveness of virtual columns in optimizing query performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Benchmark&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;dd&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'count'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="s1"&gt;'paginate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'filter + paginate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-09-05'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'sort + paginate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="s1"&gt;'filter + sort + paginate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;fn&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'2024-09-05'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;orderBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;paginate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;iterations&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;h4&gt;
  
  
  1. Add a Virtual Column with Migration
&lt;/h4&gt;

&lt;p&gt;To improve performance, we’ll start by adding a virtual column for the &lt;code&gt;approved_at&lt;/code&gt; field. This column extracts and indexes the JSON attribute for better query performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Migrations\Migration&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Database\Schema\Blueprint&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Illuminate\Support\Facades\Schema&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Migration&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'documents'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;string&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;nullable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
                &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;virtualAs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"json_unquote(json_extract(data, '$.latest_approval_date'))"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;index&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;down&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nc"&gt;Schema&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;table&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'documents'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;Blueprint&lt;/span&gt; &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dropColumn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. Create a Trait for Virtual Fields
&lt;/h4&gt;

&lt;p&gt;We’ll create a &lt;code&gt;HasVirtualFields&lt;/code&gt; trait to ensure that virtual fields are not mistakenly saved.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;App\Models\Concerns&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;trait&lt;/span&gt; &lt;span class="nc"&gt;HasVirtualFields&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;virtualFields&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_diff_key&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;array_flip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;virtualFields&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;parent&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  3. Add the Trait and Virtual Column Property to Your Model
&lt;/h4&gt;

&lt;p&gt;In the model, include the trait and define the virtual fields. This ensures that any virtual columns are properly managed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\Concerns\HasVirtualFields&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;HasVirtualFields&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;array&lt;/span&gt; &lt;span class="nv"&gt;$virtualFields&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'approved_at'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;];&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  4. Testing Environment
&lt;/h4&gt;

&lt;p&gt;To test the performance improvements, we’ll generate fake data and benchmark the queries before and after using virtual columns. Use the following provisioning script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;500&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;250&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  6. Wrapping Up with Unit Tests
&lt;/h4&gt;

&lt;p&gt;Write tests to verify that the virtual column works as expected. Here’s an example test suite:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;Tests\Feature\Models&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;Tests\TestCase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;App\Models\Document&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DocumentTest&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;TestCase&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="n"&gt;testApprovedAt&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fake&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;dateTimeBetween&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;DATE_ATOM&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="nv"&gt;$document&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;factory&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
            &lt;span class="s1"&gt;'data'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
                &lt;span class="s1"&gt;'latest_approval_date'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;]);&lt;/span&gt;
        &lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;refresh&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;assertEquals&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$document&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;approved_at&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This complete solution ensures that your JSON columns can be optimized for performance, particularly for large datasets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion and Best Practices
&lt;/h2&gt;

&lt;p&gt;Using virtual columns with indexing can dramatically improve performance when working with large datasets and JSON columns. By transitioning from nested JSON queries to indexed virtual columns, I was able to reduce query times by &lt;strong&gt;up to 36x&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Practices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use virtual columns to index frequently queried JSON attributes.&lt;/li&gt;
&lt;li&gt;Always benchmark before and after implementing changes to measure real performance improvements.&lt;/li&gt;
&lt;li&gt;Ensure your database structure evolves with your data as it scales, especially with JSON-heavy models.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Originally posted on &lt;a href="https://bcd.dev/post/optimizing-sorting-and-filtering-on-json-columns-in-laravel-with-indexed-virtual-columns-165" rel="noopener noreferrer"&gt;bcd.dev&lt;/a&gt;&lt;/p&gt;

</description>
      <category>databaseoptimization</category>
      <category>mysql</category>
      <category>phpdevelopment</category>
      <category>jsonprocessing</category>
    </item>
    <item>
      <title>Cracking a coding test interview - breakdown</title>
      <dc:creator>Babacar Cisse DIA</dc:creator>
      <pubDate>Tue, 28 Jan 2020 11:54:26 +0000</pubDate>
      <link>https://dev.to/bcdbuddy/cracking-a-coding-test-interview-breakdown-jj0</link>
      <guid>https://dev.to/bcdbuddy/cracking-a-coding-test-interview-breakdown-jj0</guid>
      <description>&lt;h1&gt;
  
  
  Cracking a coding test interview
&lt;/h1&gt;

&lt;p&gt;Coding interviews are always for me an opportunity to learn and grow which is why I wanted to share you my thought process for this one I found this morning at &lt;code&gt;letsrevolutionizetesting.com&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;What I saw when I visited the page&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4f3eplbe161ukupz47m8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4f3eplbe161ukupz47m8.png" alt="home page" width="642" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I revisited the application form&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6jzzz0onbw9tvbdmxgxq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6jzzz0onbw9tvbdmxgxq.png" alt="application_form" width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted to know what technology was used for this&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frv4uyg6h7xezcnu1l1xl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Frv4uyg6h7xezcnu1l1xl.png" alt="server discovery" width="800" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I was happy to find out it was ruby&lt;/p&gt;

&lt;p&gt;And the hint was suggesting I should try json and I did. If you know ruby on rails then it comes to you naturally&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5y8dnhklrcv1er1stky8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F5y8dnhklrcv1er1stky8.png" alt="request" width="654" height="241"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But now I am in front of the page with this json payload. It says follow so I followed the link.&lt;br&gt;
Once...&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fszq55zdd3gjyq6ny12ws.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fszq55zdd3gjyq6ny12ws.png" alt="request id json" width="698" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Twice...&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpaa5azj663n9r9rc8m4k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpaa5azj663n9r9rc8m4k.png" alt="request twice" width="696" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then I said wait...&lt;br&gt;
&lt;a href="https://i.giphy.com/media/26gR2BU2Hrt9HSN6E/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/26gR2BU2Hrt9HSN6E/giphy.gif" alt="but wait..." width="480" height="424"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It was too good to be true. So you have two choices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;either you go follow one by one the id chain&lt;/li&gt;
&lt;li&gt;or you can just write a bit of function like I did
&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffcvnaz1c80eeot7vhxl3.png" alt="Alt Text" width="800" height="553"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the last page: The holy grale&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgvyfi17l05brcptlwf0m.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fgvyfi17l05brcptlwf0m.gif" alt="result" width="600" height="337"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You could have go for an iterative version with a loop&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrap up
&lt;/h1&gt;

&lt;p&gt;I guess at RainForest they will have to make a new test since you know the answer for this one.&lt;br&gt;
Overall I think it way simple enough. We just needed to take each problem one at the time and yeah every beginner can do it too.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>career</category>
    </item>
    <item>
      <title>Supercharge your expressJs Views</title>
      <dc:creator>Babacar Cisse DIA</dc:creator>
      <pubDate>Wed, 15 Jan 2020 15:36:13 +0000</pubDate>
      <link>https://dev.to/bcdbuddy/supercharge-your-expressjs-views-31ff</link>
      <guid>https://dev.to/bcdbuddy/supercharge-your-expressjs-views-31ff</guid>
      <description>&lt;h1&gt;
  
  
  Supercharge your expressJs Views
&lt;/h1&gt;

&lt;p&gt;On the following few lines, I want to share with you how I added mixins to my expressjs application.&lt;/p&gt;

&lt;h1&gt;
  
  
  Add mixins to your views
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;Mix from laravel-mix (if you're from php world you know what I am saying)
With laravel and mix, you're very likely to have the following snippets in your code base:
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--55AJFl6X--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/2mh24xhvgwgwryrysykv.png" alt="Alt Text" width="800" height="348"&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Yes this is Pug (ex jade) syntax&lt;/p&gt;

&lt;h2&gt;
  
  
  Explanation of express mix helper
&lt;/h2&gt;

&lt;p&gt;You are most likely asking yourself where the hell this &lt;code&gt;mix&lt;/code&gt; method is coming from so here it is.&lt;br&gt;
&lt;a href="https://i.giphy.com/media/3oEjHOezvV1v2GN07S/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/3oEjHOezvV1v2GN07S/giphy.gif" alt="WTH meme" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;TLDR;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;locals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../assets/mix-manifest.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;requestedFilename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileObject&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;requestedFilename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; not found in mix manifest. Manifest: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;requestedFilename&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I read the file outputed by webpack on build&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileObject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readFileSync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__dirname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../assets/mix-manifest.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;then I return the value matching to the key which is the filename in our case&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--gfoUkgnt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/bykyuvc2n7pabko3x1ee.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--gfoUkgnt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/bykyuvc2n7pabko3x1ee.png" alt="Alt Text" width="679" height="139"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;requestedFilename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fileObject&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;requestedFilename&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Raise server error in case the file is not there. Should not happen but hey you never know when things can go wrong &lt;a href="https://i.giphy.com/media/U6Fxnc2jTlBh2GKCTU/giphy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/U6Fxnc2jTlBh2GKCTU/giphy.gif" alt="meme:dont-know" width="495" height="305"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;requestedFilename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; not found in mix manifest. Manifest: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fileObject&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Wrap up
&lt;/h1&gt;

&lt;p&gt;Now you have some a nice helper function serving the latest build of webpack with a content hash to be fully efficient cache wise.&lt;br&gt;
You're welcome!&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>javascript</category>
      <category>pug</category>
      <category>node</category>
    </item>
    <item>
      <title># Migrate to google captcha to v3. No more "No, I am not a robot"</title>
      <dc:creator>Babacar Cisse DIA</dc:creator>
      <pubDate>Fri, 10 Jan 2020 10:50:38 +0000</pubDate>
      <link>https://dev.to/bcdbuddy/migrate-to-google-captcha-to-v3-no-more-no-i-am-not-a-robot-2bob</link>
      <guid>https://dev.to/bcdbuddy/migrate-to-google-captcha-to-v3-no-more-no-i-am-not-a-robot-2bob</guid>
      <description>&lt;h1&gt;
  
  
  google captcha migration to v3. No more "No, I am not a robot"
&lt;/h1&gt;

&lt;p&gt;If you did not have one, you will need to create an app here:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ux-K1rzw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/eov1myobwez63y6sfva6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ux-K1rzw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/eov1myobwez63y6sfva6.png" alt="Google create" width="800" height="435"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;no more captcha. Verification happen under the hood &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;before: 
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--67wNzroN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/w96ce916rxbdksi7oskt.png" alt="form before" width="536" height="487"&gt;
&lt;/li&gt;
&lt;li&gt;after: 
&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---2sSKSAX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/mhu8bid1zj2z23kynaua.png" alt="form after" width="574" height="572"&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You can check google answer &lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kBL_IUxN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/w7u61p2sks6ndakefbi2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kBL_IUxN--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/w7u61p2sks6ndakefbi2.png" alt="google response" width="800" height="599"&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
I consider action: "contactPage", score &amp;gt; .8 to be a valid request. You can use your own&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can give the user ip as optional param. (I don't. Google has already enough data on us)&lt;/p&gt;

&lt;p&gt;The front end code &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--vxQE_xIs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/krhbftdk6a0q06nyruww.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vxQE_xIs--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/krhbftdk6a0q06nyruww.png" alt="front" width="382" height="178"&gt;&lt;/a&gt;&lt;br&gt;
The back end code &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mBe2ENEX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/5db8l5a8h319m9th0w93.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mBe2ENEX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/5db8l5a8h319m9th0w93.png" alt="back" width="800" height="297"&gt;&lt;/a&gt;&lt;br&gt;
Yes I am using @laravelphp.&lt;/p&gt;

&lt;p&gt;I also added a new page /contacted to have a better reporting from google analytics conversion for specific goals. Don't worry I protected it, you can't access it except you are coming from the contact form &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--H6TzSqoi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/wuwarpdyrpc8nz8c8iqh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--H6TzSqoi--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://thepracticaldev.s3.amazonaws.com/i/wuwarpdyrpc8nz8c8iqh.png" alt="twitter" width="800" height="447"&gt;&lt;/a&gt;&lt;br&gt;
Let me elaborate: Having a specific page where the user is being redirected is a good practice for analytics since you can then record the hits you are getting from that specific page (for me /contacted). You can have the same for user registration /registred&lt;/p&gt;

&lt;h1&gt;
  
  
  Wrap up
&lt;/h1&gt;

&lt;p&gt;It was amazingly fast. The migration v2 -&amp;gt; v3 is straightforward. So if you did not, go ahead it is less than 5min.&lt;br&gt;
Next step for me is to add it on my login form as well.&lt;br&gt;
Happy coding!&lt;/p&gt;

&lt;p&gt;Resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;display: &lt;a href="https://developers.google.com/recaptcha/docs/v3"&gt;https://developers.google.com/recaptcha/docs/v3&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;verify: &lt;a href="https://developers.google.com/recaptcha/docs/verify/"&gt;https://developers.google.com/recaptcha/docs/verify/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>recaptcha</category>
      <category>spambot</category>
      <category>analytics</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
