Mes flux RSS favoris

Découvrez les articles les plus intéressants que j'ai sélectionnés pour vous dans mes flux RSS. Des sujets variés allant du développement web aux dernières tendances technologiques.

Top 9 Free Resources to Learn Programming Online

Top 9 Free Resources to Learn Programming Online

21 janvier 2025

<p>Do you want to learn programming but don’t want to spend a fortune on courses? You’re in luck! Today, you can learn coding for free from some of the best platforms available online. Whether you're a complete beginner or an experienced developer looking to sharpen your skills, these free resources will help you master programming from the comfort of your home.</p> <p>Let’s explore the top 9 free resources to learn programming online and kick-start your journey to becoming a coder!</p> <h2> Top 9 Free Resources to Learn Programming Online </h2> <h2> 1. CS50 – Harvard’s Introduction to Computer Science (edX) </h2> <p>If you want to learn programming from one of the world’s top universities, Harvard’s CS50: Introduction to Computer Science is the perfect choice. Offered on edX, this course is beginner-friendly and covers:</p> <p>✅ C, Python, SQL, and JavaScript<br> ✅ Algorithms and Data Structures<br> ✅ Web Development and Cybersecurity</p> <h2> 2. freeCodeCamp </h2> <p>Want a hands-on coding experience? freeCodeCamp is an interactive platform that offers thousands of coding exercises, tutorials, and real-world projects in:</p> <p>✅ HTML, CSS, JavaScript<br> ✅ Python, Data Science, Machine Learning<br> ✅ Full-Stack Development</p> <p>What makes it stand out? You can earn certificates that help showcase your skills to potential employers!</p> <h2> 3. The Odin Project </h2> <p>If you’re serious about becoming a full-stack web developer, The Odin Project provides a structured roadmap. You’ll work on real-world projects while learning:</p> <p>✅ JavaScript, HTML, CSS<br> ✅ Git, Node.js, React<br> ✅ Back-end development</p> <p>It’s self-paced, free, and perfect for beginners looking for an all-in-one solution to web development.</p> <h2> 4. W3Schools </h2> <p>W3Schools is one of the oldest and most trusted resources for learning web technologies. It offers interactive tutorials, quizzes, and coding exercises for:</p> <p>✅ HTML, CSS, JavaScript<br> ✅ Python, SQL, PHP, and more</p> <p>If you’re looking for quick, easy-to-understand explanations, W3Schools is your go-to resource.</p> <h2> 5. Khan Academy – Computer Programming </h2> <p>Khan Academy is well-known for its high-quality free education, and its programming courses are no exception! You can learn:</p> <p>✅ JavaScript and Python<br> ✅ Animation &amp; Game Development<br> ✅ SQL &amp; Databases</p> <p>If you’re a beginner who loves a visual, interactive way of learning, Khan Academy’s approach will work wonders for you.</p> <h2> 6. GeeksforGeeks (Free Courses &amp; Articles) </h2> <p>GeeksforGeeks is one of the most comprehensive coding websites for programmers of all levels. It offers:</p> <p>✅ In-depth coding tutorials<br> ✅ Competitive programming challenges<br> ✅ Interview preparation</p> <p>If you're preparing for coding interviews or competitive coding, GeeksforGeeks is a must-have resource.</p> <h2> 7. Codecademy (Basic Free Courses) </h2> <p>Codecademy offers interactive coding lessons where you can practice in your browser. Although it has a paid Pro version, its free courses still cover a lot, including:</p> <p>✅ Python, JavaScript, Java<br> ✅ Web development (HTML, CSS)<br> ✅ SQL and Data Science</p> <p>It’s perfect for beginners who want hands-on coding experience without setting up software.</p> <h2> 8. MIT OpenCourseWare – Introduction to Computer Science </h2> <p>MIT offers its legendary programming courses for free through OpenCourseWare. The Introduction to Computer Science and Programming in Python course is one of the best:</p> <p>✅ Learn Python from scratch<br> ✅ Dive deep into algorithms and problem-solving<br> ✅ Gain a solid foundation in computer science</p> <p>If you want an academic-style learning experience, this is a great option.</p> <h2> 9. YouTube – Best Free Programming Channels </h2> <p>Who says you need to stick to traditional courses? YouTube has amazing programming channels where you can learn from top experts. Some of the best ones include:</p> <p>📌 Traversy Media – Web development tutorials<br> 📌 CS Dojo – Python, algorithms, and coding interviews<br> 📌 The Net Ninja – JavaScript, React, and more<br> 📌 Programming with Mosh – Python, JavaScript, and C#</p> <p>YouTube is completely free, and you can learn at your own pace!</p> <h2> Final Thoughts – Where Should You Start? </h2> <p>With so many incredible free resources available, it can be overwhelming to choose where to start. Here’s a quick guide:</p> <p>👉 If you’re a complete beginner: Start with freeCodeCamp or W3Schools.<br> 👉 If you want a structured course: Try CS50 or MIT OpenCourseWare.<br> 👉 If you love interactive coding: Go for Codecademy or The Odin Project.<br> 👉 If you prefer video tutorials: Explore YouTube or Khan Academy.</p> <p>The key is to start coding today and keep practicing. The more you code, the better you get!</p> <p>🚀 Which free resource do you like the most? Let me know in the comments!</p>

Lire l'article Ouvrir Top 9 Free Resources to Learn Programming Online dans un nouvel onglet
Form management

Form management

21 janvier 2025

<p>Hi everyone!</p> <p>I have a question about the types from the new hook 'useActionState'.</p> <p>Actually, I'm working on a project and I need some extra types for my action function</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbxewm33ed1v9kqmgceq8.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbxewm33ed1v9kqmgceq8.png" alt="A snippet of types from React 19v" width="800" height="205"></a></p> <p>Why don't we have an extra Generic Type to return from the action? Does the return really need to be equal to the initial state?</p> <p>In a real use case, the return from the action can be different from the entry data, such as an error object like:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight javascript"><code> <span class="c1">// INPUT DATA</span> <span class="p">{</span> <span class="nl">email</span><span class="p">:</span> <span class="dl">'</span><span class="s1">user@email.com</span><span class="dl">'</span> <span class="p">}</span> <span class="c1">// OUTPUT DATA</span> <span class="p">{</span> <span class="na">email</span><span class="p">:</span> <span class="p">{</span> <span class="na">value</span><span class="p">:</span> <span class="dl">'</span><span class="s1">user@email.com</span><span class="dl">'</span> <span class="na">state</span><span class="p">:</span> <span class="p">{</span> <span class="na">error</span><span class="p">:</span> <span class="p">{</span> <span class="na">message</span><span class="p">:</span> <span class="kc">null</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <p><strong>Reference</strong></p> <ul> <li><a href="https://react.dev/reference/react/useActionState" rel="noopener noreferrer">https://react.dev/reference/react/useActionState</a></li> <li><a href="https://react.dev/blog/2024/12/05/react-19#whats-new-in-react-19" rel="noopener noreferrer">https://react.dev/blog/2024/12/05/react-19#whats-new-in-react-19</a></li> </ul>

Lire l'article Ouvrir Form management dans un nouvel onglet
"Transforming Education: The Power of Social Determinants and AI Collaboration"

"Transforming Education: The Power of Social Determinants and AI Collaboration"

21 janvier 2025

<p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fugpehvbwbspzkwvaxgny.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fmetafy-bucket%2Fblogheader160008%3F" class="article-body-image-wrapper"><img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fugpehvbwbspzkwvaxgny.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fmetafy-bucket%2Fblogheader160008%3F" width="800" height="457"></a></p> <p>In an era where education is often seen as the great equalizer, why do disparities still persist? The answer lies not just in classrooms but in the intricate web of social determinants that shape every student's learning experience. From socioeconomic status to access to healthcare, these factors profoundly influence educational outcomes and opportunities. But what if we could harness the power of artificial intelligence (AI) to bridge these gaps? Imagine a world where AI doesn't merely serve as a tool for personalized learning but actively collaborates with educators and communities to dismantle barriers created by inequality. In this blog post, we will explore how understanding social determinants can transform education while leveraging AI's capabilities to enhance learning outcomes for all students. Through compelling case studies and insights into current challenges, we'll uncover innovative strategies that are already making waves in educational equity. Are you ready to join us on this journey toward transforming education? Together, we can advocate for change and create a future where every learner thrives—regardless of their background or circumstances. Dive deeper with us as we unveil the potential of this powerful collaboration!</p> <h1>Understanding Social Determinants in Education</h1> <p>Social determinants of education (SDoEd) encompass various factors that significantly influence students' educational achievements. The development of an ontology for SDoEd, utilizing a Human-AI collaborative approach, highlights the intricate relationship between socio-economic status, family background, and access to resources. This standardized framework consists of 231 domain concepts and emphasizes how these elements intertwine with health and well-being. By addressing these social determinants, we can tackle issues like poverty and inequality while improving overall quality of life.</p> <h2>Importance of the SDoEd Ontology</h2> <p>The ontology serves as a vital tool for organizing knowledge within the education sector. It was validated through rigorous peer-reviewed research and expert evaluations from reputable sources such as PubMed Central and the American Educational Research Association. By providing insights into educational disparities, this structured framework aims to enhance understanding among educators and policymakers regarding how external factors shape learning opportunities. Continued research is essential to ensure its effectiveness in real-world applications, ultimately promoting equity in educational settings across diverse communities.</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fugpehvbwbspzkwvaxgny.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fmetafy-bucket%2FunderstandingSocialDeterminantsInEducation.jpg%3F" class="article-body-image-wrapper"><img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fugpehvbwbspzkwvaxgny.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fmetafy-bucket%2FunderstandingSocialDeterminantsInEducation.jpg%3F" width="800" height="457"></a></p> <h1>The Role of AI in Enhancing Learning Outcomes</h1> <p>Artificial Intelligence (AI) plays a pivotal role in enhancing learning outcomes by addressing the complex interplay between social determinants and educational achievements. Through the development of an ontology for Social Determinants of Education (SDoEd), AI facilitates a structured understanding of factors such as socio-economic status, family background, and resource accessibility. This ontology comprises 231 domain concepts, enabling educators to identify barriers that hinder student success effectively.</p> <h2>Human-AI Collaboration</h2> <p>The collaborative approach involving human experts and advanced AI models like ChatGPT-3.5 ensures rigorous validation against peer-reviewed research. By organizing knowledge within education, this framework promotes equity by illuminating how socio-environmental factors impact learning opportunities. Such insights are crucial for developing targeted interventions aimed at reducing disparities in education and improving overall quality of life for students from diverse backgrounds.</p> <p>Furthermore, ongoing research is essential to refine these tools further, ensuring they remain relevant and effective in real-world educational settings. As we harness the power of AI to analyze vast datasets related to SDoEd, we can foster environments where every learner has access to equitable resources necessary for their academic growth.# Case Studies: Successful AI and Social Determinant Integration</p> <p>The integration of Artificial Intelligence (AI) with the understanding of Social Determinants of Education (SDoEd) has yielded promising results in enhancing educational outcomes. One notable case study involved the development of an ontology that encapsulates 231 domain concepts, focusing on socio-economic status, family background, and resource accessibility. This ontology was crafted through a Human-AI collaborative approach utilizing ChatGPT-3.5-010422, which facilitated comprehensive validation against peer-reviewed research and expert insights.</p> <h2>Impact on Educational Equity</h2> <p>By organizing knowledge around SDoEd, this framework highlights how interconnected factors influence students' academic achievements. The successful application of this ontology demonstrates its potential to address disparities in education by providing educators with actionable insights into the life circumstances affecting their students. Furthermore, it emphasizes the necessity for continuous research to refine these tools further—ensuring they remain effective in promoting equity within educational settings while also contributing to broader societal improvements such as poverty alleviation and health behavior enhancement.# Challenges in Merging AI with Educational Equity</p> <p>Integrating AI into educational systems presents significant challenges, particularly regarding equity. One major issue is the inherent bias present in data used to train AI models. If these datasets reflect existing inequalities—such as socio-economic disparities or limited access to resources—the resulting algorithms may perpetuate these biases, exacerbating inequities rather than alleviating them. Additionally, there is a risk of over-reliance on technology that could marginalize students who lack digital literacy or access to devices and internet connectivity.</p> <h2>Addressing Social Determinants</h2> <p>The development of an ontology for Social Determinants of Education (SDoEd) highlights the need for a comprehensive understanding of how various factors influence educational outcomes. This framework can aid in identifying gaps where AI interventions might fail to address underlying issues like poverty and family background. Furthermore, collaboration between educators and technologists is essential; without input from those directly involved in education, solutions may overlook critical contextual elements necessary for fostering equitable learning environments.</p> <p>In conclusion, while merging AI with education holds promise for enhancing learning experiences, it requires careful consideration of social determinants and potential biases to ensure that all students benefit equally from technological advancements.</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fugpehvbwbspzkwvaxgny.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fmetafy-bucket%2FchallengesInMergingAiWithEducationalEquity.jpg%3F" class="article-body-image-wrapper"><img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fugpehvbwbspzkwvaxgny.supabase.co%2Fstorage%2Fv1%2Fobject%2Fpublic%2Fmetafy-bucket%2FchallengesInMergingAiWithEducationalEquity.jpg%3F" width="800" height="457"></a></p> <h1>Future Trends: The Next Frontier for Education Transformation</h1> <p>The future of education transformation lies in the integration of Social Determinants of Education (SDoEd) with advanced AI technologies. By employing a Human-AI collaborative approach, such as utilizing ChatGPT-3.5, educators can gain deeper insights into how socio-economic factors and family backgrounds influence student outcomes. This ontology-based framework organizes 231 domain concepts that connect educational achievements to broader social contexts, emphasizing the need for equitable access to resources. As we move forward, leveraging these tools will not only enhance understanding but also drive initiatives aimed at reducing disparities in education.</p> <h2>Importance of Continuous Research and Validation</h2> <p>Continuous research is vital for refining the SDoEd ontology's application within educational settings. Evaluating concept pairs and ensuring accurate categorization under main categories are essential steps toward building a robust framework that addresses educational inequities effectively. Furthermore, making this ontology accessible on platforms like GitHub encourages collaboration among researchers and practitioners who aim to explore innovative solutions tailored to diverse learning environments. Emphasizing interdisciplinary partnerships between educators, technologists, and policymakers will be crucial in shaping an inclusive future where every learner has equal opportunities to succeed academically and socially.</p> <p>By focusing on these emerging trends in education transformation through technology-driven frameworks like SDoEd, stakeholders can foster systemic changes that promote equity across various dimensions of learning experiences.</p> <h1>How to Get Involved: Advocating for Change</h1> <p>Advocating for change in education requires a multifaceted approach that emphasizes the importance of social determinants. Engaging with local communities, educational institutions, and policymakers can create awareness about how socio-economic factors impact student outcomes. Start by participating in community forums or workshops focused on education equity; these platforms often provide opportunities to voice concerns and propose solutions. Collaborate with organizations dedicated to addressing educational disparities—volunteering your time or expertise can amplify efforts toward systemic change. Additionally, leveraging social media campaigns can help raise awareness about the significance of Social Determinants of Education (SDoEd), fostering a broader dialogue around improving access and resources.</p> <h2>Building Collaborative Networks</h2> <p>Creating alliances among educators, parents, students, and advocacy groups is crucial for effective change. By sharing knowledge through collaborative networks, stakeholders can collectively address issues related to poverty alleviation and inequality in education. Utilize online platforms like GitHub where frameworks such as SDoEd ontology are available; this encourages further exploration into structured approaches that analyze complex interactions affecting educational opportunities. Engaging with research initiatives not only enhances understanding but also contributes valuable insights towards developing practical solutions aimed at promoting equity within educational settings.</p> <p>In conclusion, the intersection of social determinants and artificial intelligence presents a transformative opportunity for education. Understanding how factors such as socioeconomic status, access to resources, and community support influence learning outcomes is crucial in creating equitable educational environments. AI can enhance these efforts by personalizing learning experiences and providing insights that help educators address individual student needs more effectively. Successful case studies demonstrate the potential of integrating AI with an awareness of social determinants to foster improved academic performance and engagement among diverse populations. However, challenges remain in ensuring that this technology is implemented equitably across all demographics. As we look toward future trends in education transformation, it becomes essential for stakeholders—educators, policymakers, and communities—to advocate for inclusive practices that harness both AI capabilities and an understanding of social contexts to create lasting change in educational equity. Engaging actively in these discussions will be vital for shaping a more just educational landscape where every learner has the opportunity to thrive.</p> <h1>FAQs</h1> <h3>1. What are social determinants in education?</h3> <p>Social determinants in education refer to the various social, economic, and environmental factors that influence a student's ability to learn and succeed academically. These can include socioeconomic status, access to healthcare, family support systems, community resources, and educational opportunities.</p> <h3>2. How does AI enhance learning outcomes in education?</h3> <p>AI enhances learning outcomes by providing personalized learning experiences tailored to individual student needs. It can analyze data on student performance to identify strengths and weaknesses, recommend resources for improvement, automate administrative tasks for educators, and facilitate adaptive learning technologies that adjust content based on real-time feedback.</p> <h3>3. Can you provide examples of successful integration of AI with social determinants in education?</h3> <p>Yes! Successful case studies include programs where AI is used alongside community-based initiatives that address food insecurity or mental health services within schools. For instance, some districts have implemented AI-driven platforms that connect students with local resources while simultaneously tracking their academic progress.</p> <h3>4. What challenges exist when merging AI with educational equity?</h3> <p>Challenges include ensuring equitable access to technology across diverse populations, addressing biases present in AI algorithms which may perpetuate existing inequalities, training educators effectively on how to use these tools responsibly and ethically, as well as securing funding for comprehensive implementation strategies.</p> <h3>5. How can individuals get involved in advocating for change regarding the integration of social determinants and AI in education?</h3> <p>Individuals can advocate for change by participating in local school board meetings focused on educational policy reform; supporting organizations dedicated to improving educational equity; volunteering with programs aimed at assisting underprivileged students; promoting awareness about the importance of integrating social determinants into educational frameworks; or engaging with policymakers through petitions or campaigns highlighting these issues.</p>

Lire l'article Ouvrir "Transforming Education: The Power of Social Determinants and AI Collaboration" dans un nouvel onglet
Building a REST API with Golang, Gin, and Pocketbase

Building a REST API with Golang, Gin, and Pocketbase

21 janvier 2025

<h3> Introduction </h3> <p>Building a REST API with modern technologies can be an engaging yet complex process, especially when you are working with unfamiliar stacks. As a Go developer, I decided to explore the combination of Golang with the Gin framework and Pocketbase for building a REST API. This choice was driven by a desire to experiment with a different tech stack while also considering the positive feedback I had heard from the developer community regarding Pocketbase's user-friendly features.</p> <p>We’ll walk you through setting up the environment, configuring the API routes, and creating a service layer to interact with Pocketbase for user authentication and data management. By the end of this tutorial, you will have a fully functional REST API capable of user registration and login.</p> <h3> Why Choose Gin and Pocketbase? </h3> <h4> Gin Framework: </h4> <ul> <li> <strong>Performance</strong>: Known for its speed and low latency, making it ideal for high-performance applications.</li> <li> <strong>Simplicity and Flexibility</strong>: Easy to set up, scale, and maintain.</li> <li> <strong>Middleware Support</strong>: Built-in middleware enables seamless integration of common features like logging and authentication.</li> </ul> <h4> Pocketbase: </h4> <ul> <li> <strong>User Management</strong>: Out-of-the-box support for user registration, login, and password reset functionalities.</li> <li> <strong>Real-Time Database</strong>: Simplifies real-time data management with minimal configuration.</li> <li> <strong>Ease of Use</strong>: Pocketbase abstracts away many backend complexities, allowing developers to focus on building the core application.</li> </ul> <h4> ⚠️ <strong>Important Note About Pocketbase</strong>: </h4> <p><em><strong>Pocketbase</strong> is under active development and may undergo breaking changes before version 1.0.0. It is <strong>not recommended for production use</strong> unless you are comfortable with frequent updates and manual migrations.</em></p> <h3> Prerequisites </h3> <ol> <li> <strong>Golang</strong>: Install Go from <a href="https://golang.org/dl/" rel="noopener noreferrer">Go Downloads</a>.</li> <li> <strong>GitHub Account</strong>: Required for cloning repositories and managing code.</li> <li> <strong>Pocketbase</strong>: Download the latest release from <a href="https://github.com/pocketbase/pocketbase" rel="noopener noreferrer">Pocketbase GitHub</a>.</li> </ol> <h3> Setting Up the Project Structure </h3> <p>The directory structure of the project is as follows:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight plaintext"><code>walkit/ ├── .github/ ├── cmd/ │ └── server/ ├── config/ ├── internal/ │ ├── middleware/ │ ├── handler/ │ ├── model/ │ ├── repository/ │ ├── service/ │ ├── routes/ ├── pb_data/ ├── pkg/ │ ├── util/ │ └── logger/ ├── air.toml ├── .env ├── Dockerfile ├── pocketbase ├── Makefile ├── go.mod ├── go.sum └── README.md </code></pre> </div> <h3> Setting Up Pocketbase </h3> <h4> Download and Install Pocketbase: </h4> <ol> <li>Download the latest release of Pocketbase from the <a href="https://github.com/pocketbase/pocketbase" rel="noopener noreferrer">GitHub repository</a>.</li> <li>Extract the files and place them in your project folder.</li> <li>To start Pocketbase, run the following command: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> ./pocketbase serve </code></pre> </div> <p>This will start Pocketbase at <code>http://127.0.0.1:8090</code>.</p> <ol> <li>Navigate to the Pocketbase dashboard at <code>http://127.0.0.1:8090/_/</code> and set up a root password for the admin interface.</li> </ol> <p>Once the server is running, Pocketbase provides two essential endpoints:</p> <ul> <li>REST API: <code>http://127.0.0.1:8090/api/</code> </li> <li>Dashboard: <code>http://127.0.0.1:8090/_/</code> </li> </ul> <h3> Configuring API URLs </h3> <p>In the <code>config.go</code> file, we'll use <strong>Viper</strong> to manage and load configuration settings, such as the Pocketbase API URL and JWT secret. This ensures that the Golang application can securely interact with Pocketbase for user authentication and management.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight go"><code><span class="k">package</span> <span class="n">config</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"log"</span> <span class="s">"github.com/spf13/viper"</span> <span class="p">)</span> <span class="k">type</span> <span class="n">Config</span> <span class="k">struct</span> <span class="p">{</span> <span class="n">BaseURL</span> <span class="kt">string</span> <span class="n">JWTSecret</span> <span class="kt">string</span> <span class="n">Environment</span> <span class="kt">string</span> <span class="n">CORSAllowedOrigins</span> <span class="p">[]</span><span class="kt">string</span> <span class="n">Port</span> <span class="kt">string</span> <span class="p">}</span> <span class="k">func</span> <span class="n">LoadConfig</span><span class="p">()</span> <span class="o">*</span><span class="n">Config</span> <span class="p">{</span> <span class="n">viper</span><span class="o">.</span><span class="n">SetConfigName</span><span class="p">(</span><span class="s">"config"</span><span class="p">)</span> <span class="n">viper</span><span class="o">.</span><span class="n">SetConfigType</span><span class="p">(</span><span class="s">"yaml"</span><span class="p">)</span> <span class="n">viper</span><span class="o">.</span><span class="n">AddConfigPath</span><span class="p">(</span><span class="s">"./config"</span><span class="p">)</span> <span class="n">viper</span><span class="o">.</span><span class="n">AddConfigPath</span><span class="p">(</span><span class="s">"."</span><span class="p">)</span> <span class="n">viper</span><span class="o">.</span><span class="n">AutomaticEnv</span><span class="p">()</span> <span class="n">viper</span><span class="o">.</span><span class="n">SetDefault</span><span class="p">(</span><span class="s">"cors_allowed_origins"</span><span class="p">,</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">"*"</span><span class="p">})</span> <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">viper</span><span class="o">.</span><span class="n">ReadInConfig</span><span class="p">();</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="n">log</span><span class="o">.</span><span class="n">Printf</span><span class="p">(</span><span class="s">"Error reading config file, using defaults: %v"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="p">}</span> <span class="n">corsAllowedOrigins</span> <span class="o">:=</span> <span class="n">viper</span><span class="o">.</span><span class="n">GetStringSlice</span><span class="p">(</span><span class="s">"cors_allowed_origins"</span><span class="p">)</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">corsAllowedOrigins</span><span class="p">)</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span> <span class="n">corsAllowedOrigins</span> <span class="o">=</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">"*"</span><span class="p">}</span> <span class="p">}</span> <span class="k">return</span> <span class="o">&amp;</span><span class="n">Config</span><span class="p">{</span> <span class="n">BaseURL</span><span class="o">:</span> <span class="n">viper</span><span class="o">.</span><span class="n">GetString</span><span class="p">(</span><span class="s">"pocket_base_url"</span><span class="p">),</span> <span class="n">JWTSecret</span><span class="o">:</span> <span class="n">viper</span><span class="o">.</span><span class="n">GetString</span><span class="p">(</span><span class="s">"jwt_secret"</span><span class="p">),</span> <span class="n">Environment</span><span class="o">:</span> <span class="n">viper</span><span class="o">.</span><span class="n">GetString</span><span class="p">(</span><span class="s">"app_env"</span><span class="p">),</span> <span class="n">CORSAllowedOrigins</span><span class="o">:</span> <span class="n">corsAllowedOrigins</span><span class="p">,</span> <span class="n">Port</span><span class="o">:</span> <span class="n">viper</span><span class="o">.</span><span class="n">GetString</span><span class="p">(</span><span class="s">"port"</span><span class="p">),</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <p>The <code>config.yml</code> file should be structured as follows:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight yaml"><code><span class="na">pocket_base_url</span><span class="pi">:</span> <span class="s2">"</span><span class="s">http://127.0.0.1:8090/api"</span> <span class="na">jwt_secret</span><span class="pi">:</span> <span class="s2">"</span><span class="s">your_jwt_secret_key"</span> <span class="na">app_env</span><span class="pi">:</span> <span class="s2">"</span><span class="s">development"</span> <span class="na">cors_allowed_origins</span><span class="pi">:</span> <span class="pi">-</span> <span class="s2">"</span><span class="s">*"</span> <span class="na">port</span><span class="pi">:</span> <span class="s2">"</span><span class="s">8080"</span> </code></pre> </div> <h3> Setting Up Golang with Gin </h3> <h4> Install Gin: </h4> <p>To install the Gin framework in your Go project, run the following command:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>go get <span class="nt">-u</span> github.com/gin-gonic/gin </code></pre> </div> <p>This will install Gin and its dependencies into your Go workspace.</p> <h4> API Endpoints and <code>main.go</code> Implementation </h4> <p>Here are the two primary API endpoints for registering and logging in users:</p> <ul> <li> <code>POST /api/v1/auth/register</code> – Allows a new user to register.</li> <li> <code>POST /api/v1/auth/login</code> – Allows a registered user to log in and receive a JWT token. </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight go"><code><span class="k">package</span> <span class="n">main</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"context"</span> <span class="s">"net/http"</span> <span class="s">"os"</span> <span class="s">"os/signal"</span> <span class="s">"syscall"</span> <span class="s">"time"</span> <span class="s">"github.com/gin-contrib/cors"</span> <span class="s">"github.com/gin-gonic/gin"</span> <span class="s">"github.com/rowjay007/walkit/config"</span> <span class="s">"github.com/rowjay007/walkit/internal/routes"</span> <span class="s">"github.com/rowjay007/walkit/pkg/logger"</span> <span class="p">)</span> <span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">logger</span> <span class="o">:=</span> <span class="n">logger</span><span class="o">.</span><span class="n">New</span><span class="p">()</span> <span class="n">cfg</span> <span class="o">:=</span> <span class="n">config</span><span class="o">.</span><span class="n">LoadConfig</span><span class="p">()</span> <span class="k">if</span> <span class="n">cfg</span><span class="o">.</span><span class="n">Environment</span> <span class="o">==</span> <span class="s">"production"</span> <span class="p">{</span> <span class="n">gin</span><span class="o">.</span><span class="n">SetMode</span><span class="p">(</span><span class="n">gin</span><span class="o">.</span><span class="n">ReleaseMode</span><span class="p">)</span> <span class="p">}</span> <span class="n">router</span> <span class="o">:=</span> <span class="n">gin</span><span class="o">.</span><span class="n">New</span><span class="p">()</span> <span class="n">router</span><span class="o">.</span><span class="n">Use</span><span class="p">(</span><span class="n">gin</span><span class="o">.</span><span class="n">Recovery</span><span class="p">())</span> <span class="n">corsConfig</span> <span class="o">:=</span> <span class="n">cors</span><span class="o">.</span><span class="n">DefaultConfig</span><span class="p">()</span> <span class="n">corsConfig</span><span class="o">.</span><span class="n">AllowOrigins</span> <span class="o">=</span> <span class="n">cfg</span><span class="o">.</span><span class="n">CORSAllowedOrigins</span> <span class="n">router</span><span class="o">.</span><span class="n">Use</span><span class="p">(</span><span class="n">cors</span><span class="o">.</span><span class="n">New</span><span class="p">(</span><span class="n">corsConfig</span><span class="p">))</span> <span class="n">routes</span><span class="o">.</span><span class="n">LoadRoutes</span><span class="p">(</span><span class="n">router</span><span class="p">)</span> <span class="n">srv</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="n">http</span><span class="o">.</span><span class="n">Server</span><span class="p">{</span> <span class="n">Addr</span><span class="o">:</span> <span class="s">":"</span> <span class="o">+</span> <span class="n">cfg</span><span class="o">.</span><span class="n">Port</span><span class="p">,</span> <span class="n">Handler</span><span class="o">:</span> <span class="n">router</span><span class="p">,</span> <span class="n">ReadTimeout</span><span class="o">:</span> <span class="m">15</span> <span class="o">*</span> <span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">,</span> <span class="n">WriteTimeout</span><span class="o">:</span> <span class="m">15</span> <span class="o">*</span> <span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">,</span> <span class="n">IdleTimeout</span><span class="o">:</span> <span class="m">60</span> <span class="o">*</span> <span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">,</span> <span class="p">}</span> <span class="k">go</span> <span class="k">func</span><span class="p">()</span> <span class="p">{</span> <span class="n">logger</span><span class="o">.</span><span class="n">Info</span><span class="p">(</span><span class="s">"Starting server on port "</span> <span class="o">+</span> <span class="n">cfg</span><span class="o">.</span><span class="n">Port</span><span class="p">)</span> <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">srv</span><span class="o">.</span><span class="n">ListenAndServe</span><span class="p">();</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="o">&amp;&amp;</span> <span class="n">err</span> <span class="o">!=</span> <span class="n">http</span><span class="o">.</span><span class="n">ErrServerClosed</span> <span class="p">{</span> <span class="n">logger</span><span class="o">.</span><span class="n">Fatal</span><span class="p">(</span><span class="s">"Failed to start server: "</span> <span class="o">+</span> <span class="n">err</span><span class="o">.</span><span class="n">Error</span><span class="p">())</span> <span class="p">}</span> <span class="p">}()</span> <span class="n">quit</span> <span class="o">:=</span> <span class="nb">make</span><span class="p">(</span><span class="k">chan</span> <span class="n">os</span><span class="o">.</span><span class="n">Signal</span><span class="p">,</span> <span class="m">1</span><span class="p">)</span> <span class="n">signal</span><span class="o">.</span><span class="n">Notify</span><span class="p">(</span><span class="n">quit</span><span class="p">,</span> <span class="n">syscall</span><span class="o">.</span><span class="n">SIGINT</span><span class="p">,</span> <span class="n">syscall</span><span class="o">.</span><span class="n">SIGTERM</span><span class="p">)</span> <span class="o">&lt;-</span><span class="n">quit</span> <span class="n">logger</span><span class="o">.</span><span class="n">Info</span><span class="p">(</span><span class="s">"Shutting down server..."</span><span class="p">)</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">cancel</span> <span class="o">:=</span> <span class="n">context</span><span class="o">.</span><span class="n">WithTimeout</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">Background</span><span class="p">(),</span> <span class="m">5</span><span class="o">*</span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span> <span class="k">defer</span> <span class="n">cancel</span><span class="p">()</span> <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">srv</span><span class="o">.</span><span class="n">Shutdown</span><span class="p">(</span><span class="n">ctx</span><span class="p">);</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="n">logger</span><span class="o">.</span><span class="n">Fatal</span><span class="p">(</span><span class="s">"Server forced to shutdown: "</span> <span class="o">+</span> <span class="n">err</span><span class="o">.</span><span class="n">Error</span><span class="p">())</span> <span class="p">}</span> <span class="n">logger</span><span class="o">.</span><span class="n">Info</span><span class="p">(</span><span class="s">"Server exiting"</span><span class="p">)</span> <span class="p">}</span> </code></pre> </div> <h3> Integrating Repository, Service, and Handler </h3> <h4> Repository Layer (<code>repository.go</code>): </h4> <p>This layer interacts directly with Pocketbase for data management, such as registering users or logging them in.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight go"><code><span class="k">package</span> <span class="n">repository</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"bytes"</span> <span class="s">"encoding/json"</span> <span class="s">"fmt"</span> <span class="s">"net/http"</span> <span class="s">"github.com/rowjay007/walkit/config"</span> <span class="s">"github.com/rowjay007/walkit/internal/model"</span> <span class="p">)</span> <span class="k">func</span> <span class="n">AuthAPI</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span> <span class="k">return</span> <span class="n">config</span><span class="o">.</span><span class="n">LoadConfig</span><span class="p">()</span><span class="o">.</span><span class="n">BaseURL</span> <span class="o">+</span> <span class="s">"/collections/users"</span> <span class="p">}</span> <span class="k">func</span> <span class="n">RegisterUser</span><span class="p">(</span><span class="n">user</span> <span class="n">model</span><span class="o">.</span><span class="n">User</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span> <span class="n">userJSON</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">json</span><span class="o">.</span><span class="n">Marshal</span><span class="p">(</span><span class="n">user</span><span class="p">)</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"error marshaling user data: %w"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="p">}</span> <span class="n">resp</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">http</span><span class="o">.</span><span class="n">Post</span><span class="p">(</span><span class="n">AuthAPI</span><span class="p">(),</span> <span class="s">"application/json"</span><span class="p">,</span> <span class="n">bytes</span><span class="o">.</span><span class="n">NewBuffer</span><span class="p">(</span><span class="n">userJSON</span><span class="p">))</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"error making request: %w"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="p">}</span> <span class="k">defer</span> <span class="n">resp</span><span class="o">.</span><span class="n">Body</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span> <span class="k">if</span> <span class="n">resp</span><span class="o">.</span><span class="n">StatusCode</span> <span class="o">!=</span> <span class="n">http</span><span class="o">.</span><span class="n">StatusOK</span> <span class="o">&amp;&amp;</span> <span class="n">resp</span><span class="o">.</span><span class="n">StatusCode</span> <span class="o">!=</span> <span class="n">http</span><span class="o">.</span><span class="n">StatusCreated</span> <span class="p">{</span> <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"registration failed: %v"</span><span class="p">,</span> <span class="n">resp</span><span class="o">.</span><span class="n">Status</span><span class="p">)</span> <span class="p">}</span> <span class="k">return</span> <span class="no">nil</span> <span class="p">}</span> <span class="k">func</span> <span class="n">LoginUser</span><span class="p">(</span><span class="n">login</span> <span class="n">model</span><span class="o">.</span><span class="n">LoginRequest</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="n">model</span><span class="o">.</span><span class="n">LoginResponse</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span> <span class="n">loginJSON</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">json</span><span class="o">.</span><span class="n">Marshal</span><span class="p">(</span><span class="n">login</span><span class="p">)</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="k">return</span> <span class="no">nil</span><span class="p">,</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"error marshaling login data: %w"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="p">}</span> <span class="n">req</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">http</span><span class="o">.</span><span class="n">NewRequest</span><span class="p">(</span><span class="s">"POST"</span><span class="p">,</span> <span class="n">AuthAPI</span><span class="p">()</span><span class="o">+</span><span class="s">"/auth-with-password"</span><span class="p">,</span> <span class="n">bytes</span><span class="o">.</span><span class="n">NewBuffer</span><span class="p">(</span><span class="n">loginJSON</span><span class="p">))</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="k">return</span> <span class="no">nil</span><span class="p">,</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"error creating request: %w"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="p">}</span> <span class="n">req</span><span class="o">.</span><span class="n">Header</span><span class="o">.</span><span class="n">Set</span><span class="p">(</span><span class="s">"Content-Type"</span><span class="p">,</span> <span class="s">"application/json"</span><span class="p">)</span> <span class="n">client</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="n">http</span><span class="o">.</span><span class="n">Client</span><span class="p">{}</span> <span class="n">resp</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">client</span><span class="o">.</span><span class="n">Do</span><span class="p">(</span><span class="n">req</span><span class="p">)</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="k">return</span> <span class="no">nil</span><span class="p">,</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"error making request: %w"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="p">}</span> <span class="k">defer</span> <span class="n">resp</span><span class="o">.</span><span class="n">Body</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span> <span class="k">var</span> <span class="n">response</span> <span class="n">model</span><span class="o">.</span><span class="n">LoginResponse</span> <span class="c">// Handle response decoding here</span> <span class="k">return</span> <span class="o">&amp;</span><span class="n">response</span><span class="p">,</span> <span class="no">nil</span> <span class="p">}</span> </code></pre> </div> <h4> Service Layer (<code>service.go</code>): </h4> <p>This layer handles business logic and interacts with the repository.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight go"><code><span class="k">package</span> <span class="n">service</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"github.com/rowjay007/walkit/internal/model"</span> <span class="s">"github.com/rowjay007/walkit/internal/repository"</span> <span class="p">)</span> <span class="k">func</span> <span class="n">LoginUser</span><span class="p">(</span><span class="n">login</span> <span class="n">model</span><span class="o">.</span><span class="n">LoginRequest</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="n">model</span><span class="o">.</span><span class="n">LoginResponse</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">repository</span><span class="o">.</span><span class="n">LoginUser</span><span class="p">(</span><span class="n">login</span><span class="p">)</span> <span class="p">}</span> <span class="k">func</span> <span class="n">RegisterUser</span><span class="p">(</span><span class="n">user</span> <span class="n">model</span><span class="o">.</span><span class="n">User</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span> <span class="k">return</span> <span class="n">repository</span><span class="o">.</span><span class="n">RegisterUser</span><span class="p">(</span><span class="n">user</span><span class="p">)</span> <span class="p">}</span> </code></pre> </div> <h4> Handler Layer (<code>handler.go</code>): </h4> <p>This layer handles HTTP requests and responses.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight go"><code><span class="k">package</span> <span class="n">handler</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"fmt"</span> <span class="s">"net/http"</span> <span class="s">"strings"</span> <span class="s">"github.com/gin-gonic/gin"</span> <span class="s">"github.com/rowjay007/walkit/internal/model"</span> <span class="s">"github.com/rowjay007/walkit/internal/service"</span> <span class="s">"github.com/rowjay007/walkit/pkg/util"</span> <span class="p">)</span> <span class="k">func</span> <span class="n">LoginUser</span><span class="p">(</span><span class="n">c</span> <span class="o">*</span><span class="n">gin</span><span class="o">.</span><span class="n">Context</span><span class="p">)</span> <span class="p">{</span> <span class="k">var</span> <span class="n">login</span> <span class="n">model</span><span class="o">.</span><span class="n">LoginRequest</span> <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">c</span><span class="o">.</span><span class="n">ShouldBindJSON</span><span class="p">(</span><span class="o">&amp;</span><span class="n">login</span><span class="p">);</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="n">util</span><span class="o">.</span><span class="n">RespondWithError</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">http</span><span class="o">.</span><span class="n">StatusBadRequest</span><span class="p">,</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Sprintf</span><span class="p">(</span><span class="s">"Invalid request payload: %v"</span><span class="p">,</span> <span class="n">err</span><span class="p">))</span> <span class="k">return</span> <span class="p">}</span> <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">validateLoginInput</span><span class="p">(</span><span class="n">login</span><span class="p">);</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="n">util</span><span class="o">.</span><span class="n">RespondWithError</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">http</span><span class="o">.</span><span class="n">StatusBadRequest</span><span class="p">,</span> <span class="n">err</span><span class="o">.</span><span class="n">Error</span><span class="p">())</span> <span class="k">return</span> <span class="p">}</span> <span class="n">response</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">service</span><span class="o">.</span><span class="n">LoginUser</span><span class="p">(</span><span class="n">login</span><span class="p">)</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="n">statusCode</span> <span class="o">:=</span> <span class="n">determineStatusCode</span><span class="p">(</span><span class="n">err</span><span class="p">)</span> <span class="n">util</span><span class="o">.</span><span class="n">RespondWithError</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">statusCode</span><span class="p">,</span> <span class="s">"Login failed. Please check your credentials."</span><span class="p">)</span> <span class="k">return</span> <span class="p">}</span> <span class="n">util</span><span class="o">.</span><span class="n">RespondWithJSON</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">http</span><span class="o">.</span><span class="n">StatusOK</span><span class="p">,</span> <span class="n">response</span><span class="p">)</span> <span class="p">}</span> <span class="k">func</span> <span class="n">validateLoginInput</span><span class="p">(</span><span class="n">login</span> <span class="n">model</span><span class="o">.</span><span class="n">LoginRequest</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span> <span class="k">if</span> <span class="n">strings</span><span class="o">.</span><span class="n">TrimSpace</span><span class="p">(</span><span class="n">login</span><span class="o">.</span><span class="n">Identity</span><span class="p">)</span> <span class="o">==</span> <span class="s">""</span> <span class="p">{</span> <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"identity cannot be empty"</span><span class="p">)</span> <span class="p">}</span> <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">login</span><span class="o">.</span><span class="n">Password</span><span class="p">)</span> <span class="o">&lt;</span> <span class="m">8</span> <span class="p">{</span> <span class="k">return</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"password must be at least 8 characters"</span><span class="p">)</span> <span class="p">}</span> <span class="k">return</span> <span class="no">nil</span> <span class="p">}</span> <span class="k">func</span> <span class="n">determineStatusCode</span><span class="p">(</span><span class="n">err</span> <span class="kt">error</span><span class="p">)</span> <span class="kt">int</span> <span class="p">{</span> <span class="k">if</span> <span class="n">strings</span><span class="o">.</span><span class="n">Contains</span><span class="p">(</span><span class="n">strings</span><span class="o">.</span><span class="n">ToLower</span><span class="p">(</span><span class="n">err</span><span class="o">.</span><span class="n">Error</span><span class="p">()),</span> <span class="s">"invalid credentials"</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">http</span><span class="o">.</span><span class="n">StatusUnauthorized</span> <span class="p">}</span> <span class="k">if</span> <span class="n">strings</span><span class="o">.</span><span class="n">Contains</span><span class="p">(</span><span class="n">strings</span><span class="o">.</span><span class="n">ToLower</span><span class="p">(</span><span class="n">err</span><span class="o">.</span><span class="n">Error</span><span class="p">()),</span> <span class="s">"not found"</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">http</span><span class="o">.</span><span class="n">StatusNotFound</span> <span class="p">}</span> <span class="k">return</span> <span class="n">http</span><span class="o">.</span><span class="n">StatusInternalServerError</span> <span class="p">}</span> </code></pre> </div> <h4> Response Utilities (<code>util.go</code>): </h4> <p>This file provides functions to send consistent responses.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight go"><code><span class="k">package</span> <span class="n">util</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"github.com/gin-gonic/gin"</span> <span class="p">)</span> <span class="k">func</span> <span class="n">RespondWithError</span><span class="p">(</span><span class="n">c</span> <span class="o">*</span><span class="n">gin</span><span class="o">.</span><span class="n">Context</span><span class="p">,</span> <span class="n">code</span> <span class="kt">int</span><span class="p">,</span> <span class="n">message</span> <span class="kt">string</span><span class="p">)</span> <span class="p">{</span> <span class="n">c</span><span class="o">.</span><span class="n">JSON</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">gin</span><span class="o">.</span><span class="n">H</span><span class="p">{</span><span class="s">"error"</span><span class="o">:</span> <span class="n">message</span><span class="p">})</span> <span class="p">}</span> <span class="k">func</span> <span class="n">RespondWithJSON</span><span class="p">(</span><span class="n">c</span> <span class="o">*</span><span class="n">gin</span><span class="o">.</span><span class="n">Context</span><span class="p">,</span> <span class="n">code</span> <span class="kt">int</span><span class="p">,</span> <span class="n">payload</span> <span class="k">interface</span><span class="p">{})</span> <span class="p">{</span> <span class="n">c</span><span class="o">.</span><span class="n">JSON</span><span class="p">(</span><span class="n">code</span><span class="p">,</span> <span class="n">payload</span><span class="p">)</span> <span class="p">}</span> </code></pre> </div> <h3> JWT Middleware (<code>middleware.go</code>): </h3> <p>This middleware ensures that a valid JWT token is included in the request header.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight go"><code><span class="k">package</span> <span class="n">middleware</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"fmt"</span> <span class="s">"net/http"</span> <span class="s">"strings"</span> <span class="s">"github.com/dgrijalva/jwt-go"</span> <span class="s">"github.com/gin-gonic/gin"</span> <span class="s">"github.com/rowjay007/walkit/config"</span> <span class="p">)</span> <span class="k">func</span> <span class="n">JWTAuthMiddleware</span><span class="p">(</span><span class="n">c</span> <span class="o">*</span><span class="n">gin</span><span class="o">.</span><span class="n">Context</span><span class="p">)</span> <span class="p">{</span> <span class="n">tokenString</span> <span class="o">:=</span> <span class="n">c</span><span class="o">.</span><span class="n">GetHeader</span><span class="p">(</span><span class="s">"Authorization"</span><span class="p">)</span> <span class="k">if</span> <span class="n">tokenString</span> <span class="o">==</span> <span class="s">""</span> <span class="p">{</span> <span class="n">c</span><span class="o">.</span><span class="n">JSON</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">StatusUnauthorized</span><span class="p">,</span> <span class="n">gin</span><span class="o">.</span><span class="n">H</span><span class="p">{</span><span class="s">"error"</span><span class="o">:</span> <span class="s">"Authorization token is required"</span><span class="p">})</span> <span class="n">c</span><span class="o">.</span><span class="n">Abort</span><span class="p">()</span> <span class="k">return</span> <span class="p">}</span> <span class="n">tokenString</span> <span class="o">=</span> <span class="n">strings</span><span class="o">.</span><span class="n">TrimPrefix</span><span class="p">(</span><span class="n">tokenString</span><span class="p">,</span> <span class="s">"Bearer "</span><span class="p">)</span> <span class="n">token</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">jwt</span><span class="o">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">tokenString</span><span class="p">,</span> <span class="k">func</span><span class="p">(</span><span class="n">token</span> <span class="o">*</span><span class="n">jwt</span><span class="o">.</span><span class="n">Token</span><span class="p">)</span> <span class="p">(</span><span class="k">interface</span><span class="p">{},</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="n">_</span><span class="p">,</span> <span class="n">ok</span> <span class="o">:=</span> <span class="n">token</span><span class="o">.</span><span class="n">Method</span><span class="o">.</span><span class="p">(</span><span class="o">*</span><span class="n">jwt</span><span class="o">.</span><span class="n">SigningMethodHMAC</span><span class="p">);</span> <span class="o">!</span><span class="n">ok</span> <span class="p">{</span> <span class="k">return</span> <span class="no">nil</span><span class="p">,</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Errorf</span><span class="p">(</span><span class="s">"unexpected signing method: %v"</span><span class="p">,</span> <span class="n">token</span><span class="o">.</span><span class="n">Header</span><span class="p">[</span><span class="s">"alg"</span><span class="p">])</span> <span class="p">}</span> <span class="k">return</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">(</span><span class="n">config</span><span class="o">.</span><span class="n">LoadConfig</span><span class="p">()</span><span class="o">.</span><span class="n">JWTSecret</span><span class="p">),</span> <span class="no">nil</span> <span class="p">})</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="o">||</span> <span class="o">!</span><span class="n">token</span><span class="o">.</span><span class="n">Valid</span> <span class="p">{</span> <span class="n">c</span><span class="o">.</span><span class="n">JSON</span><span class="p">(</span><span class="n">http</span><span class="o">.</span><span class="n">StatusUnauthorized</span><span class="p">,</span> <span class="n">gin</span><span class="o">.</span><span class="n">H</span><span class="p">{</span><span class="s">"error"</span><span class="o">:</span> <span class="s">"Invalid or expired token"</span><span class="p">})</span> <span class="n">c</span><span class="o">.</span><span class="n">Abort</span><span class="p">()</span> <span class="k">return</span> <span class="p">}</span> <span class="n">c</span><span class="o">.</span><span class="n">Next</span><span class="p">()</span> <span class="p">}</span> </code></pre> </div> <p>Here’s the updated conclusion with a link to the complete code:</p> <h3> Conclusion </h3> <p>In this tutorial, we’ve built a REST API using <strong>Golang</strong>, <strong>Gin</strong>, and <strong>Pocketbase</strong>. The guide covered everything from project structure to implementing user authentication with JWT tokens. We also demonstrated how to integrate multiple layers (repository, service, handler) for better modularity and scalability.</p> <p>With this setup, you can start extending your API with more features, such as user profile management, JWT token refresh, and other advanced functionalities.</p> <h3> Next Steps </h3> <ul> <li> <strong>Add Password Reset</strong>: Implement a password reset flow using JWT for authentication.</li> <li> <strong>Use More Pocketbase Features</strong>: Pocketbase offers additional real-time features that can be useful for interactive applications.</li> <li> <strong>Test the API</strong>: Write tests for API endpoints to ensure robustness.</li> <li> <strong>Deploy</strong>: Deploy the application on platforms like AWS, Google Cloud, or DigitalOcean.</li> </ul> <p>By following this tutorial, you've established a solid foundation for building secure and scalable APIs using <strong>Golang</strong>, <strong>Gin</strong>, and <strong>Pocketbase</strong>.</p> <p>You can find the complete code for this project on <a href="https://github.com/rowjay007/walkit" rel="noopener noreferrer">GitHub here</a>.</p>

Lire l'article Ouvrir Building a REST API with Golang, Gin, and Pocketbase dans un nouvel onglet
Resize in PyTorch

Resize in PyTorch

21 janvier 2025

<p><a href="//ko-fi.com/superkai">Buy Me a Coffee</a>☕</p> <p>*Memos:</p> <ul> <li> <a href="https://dev.to/hyperkai/oxfordiiitpet-in-pytorch-17kk">My post</a> explains <a href="https://pytorch.org/vision/stable/generated/torchvision.datasets.OxfordIIITPet.html" rel="noopener noreferrer">OxfordIIITPet()</a>.</li> </ul> <p><a href="https://pytorch.org/vision/main/generated/torchvision.transforms.v2.Resize.html" rel="noopener noreferrer">Resize()</a> can resize zero or more images as shown below:</p> <p>*Memos:</p> <ul> <li>The 1st argument for initialization is <code>size</code>(Required-Type:<code>int</code>, <code>tuple/list</code>(<code>int</code>) or <a href="https://pytorch.org/docs/stable/generated/torch.Tensor.size.html" rel="noopener noreferrer">size()</a>): *Memos: <ul> <li>It's <code>[height, width]</code>.</li> <li>It must be 1 &lt;= x.</li> <li> <code>None</code> can be explicitly set to it only if <code>max_size</code> isn't <code>None</code>.</li> <li>A tuple/list must be the 1D with 1 or 2 elements.</li> <li>A single value(<code>int</code> or <code>tuple/list</code>(<code>int</code>)) is applied to a smaller image's width or height edge, then the other larger width or height edge is also resized: *Memos:</li> <li>If an image's width is smaller than its height, it's <code>[size * height / width, size]</code>.</li> <li>If an image width is larger than its height, it's <code>[size, size * width / height]</code>.</li> <li>If an image width is equal to its height, it's <code>[size, size]</code>.</li> </ul> </li> <li>The 2nd argument for initialization is <code>interpolation</code>(Optional-Default:<code>InterpolationMode.BILINEAR</code>-Type:<a href="https://pytorch.org/vision/main/_modules/torchvision/transforms/functional.html" rel="noopener noreferrer">InterpolationMode</a>).</li> <li>The 3rd argument for initialization is <code>max_size</code>(Optional-Default:<code>None</code>-Type:<code>int</code>): *Memos: <ul> <li>It's only supported if <code>size</code> is a single value(<code>int</code> or <code>tuple/list</code>(<code>int</code>)).</li> <li>After <code>size</code> is applied if a larger image's width or height edge exceeds it, it's applied to a larger image's width or height edge to limit the image size, then the other smaller image's width or height edge also becomes smaller than before.</li> </ul> </li> <li>The 4th argument for initialization is <code>antialias</code>(Optional-Default:<code>True</code>-Type:<code>bool</code>). *Even if setting <code>False</code> to it, it's always <code>True</code> if <code>interpolation</code> is <code>InterpolationMode.BILINEAR</code> or <code>InterpolationMode.BICUBIC</code>. </li> <li>The 1st argument is <code>img</code>(Required-Type:<code>PIL Image</code> or <code>tensor</code>(<code>int</code>, <code>float</code>, <code>complex</code> or <code>bool</code>)): *Memos: <ul> <li>A tensor must be the 3D or more D of one or more elements.</li> <li>Don't use <code>img=</code>.</li> </ul> </li> <li> <code>v2</code> is recommended to use according to <a href="https://pytorch.org/vision/0.20/transforms.html#v1-or-v2-which-one-should-i-use" rel="noopener noreferrer">V1 or V2? Which one should I use?</a>. </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight python"><code><span class="kn">from</span> <span class="n">torchvision.datasets</span> <span class="kn">import</span> <span class="n">OxfordIIITPet</span> <span class="kn">from</span> <span class="n">torchvision.transforms.v2</span> <span class="kn">import</span> <span class="n">Resize</span> <span class="kn">from</span> <span class="n">torchvision.transforms.functional</span> <span class="kn">import</span> <span class="n">InterpolationMode</span> <span class="n">resize</span> <span class="o">=</span> <span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span> <span class="n">resize</span> <span class="o">=</span> <span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">interpolation</span><span class="o">=</span><span class="n">InterpolationMode</span><span class="p">.</span><span class="n">BILINEAR</span><span class="p">,</span> <span class="n">max_size</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">antialias</span><span class="o">=</span><span class="bp">True</span><span class="p">)</span> <span class="n">resize</span> <span class="c1"># Resize(size=[100], # interpolation=InterpolationMode.BILINEAR, # antialias=True) </span> <span class="n">resize</span><span class="p">.</span><span class="n">size</span> <span class="c1"># [100] </span> <span class="n">resize</span><span class="p">.</span><span class="n">interpolation</span> <span class="c1"># &lt;InterpolationMode.BILINEAR: 'bilinear'&gt; </span> <span class="nf">print</span><span class="p">(</span><span class="n">resize</span><span class="p">.</span><span class="n">max_size</span><span class="p">)</span> <span class="c1"># None </span> <span class="n">resize</span><span class="p">.</span><span class="n">antialias</span> <span class="c1"># True </span> <span class="n">origin_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="bp">None</span> <span class="p">)</span> <span class="n">s1000_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">1000</span><span class="p">)</span> <span class="c1"># transform=Resize(size=[1000]) </span> <span class="c1"># transform=Resize(size=[1000, 1000]) </span><span class="p">)</span> <span class="n">s100_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span> <span class="p">)</span> <span class="n">s50_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span> <span class="p">)</span> <span class="n">s10_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span> <span class="p">)</span> <span class="n">s100_180_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">180</span><span class="p">])</span> <span class="p">)</span> <span class="n">s180_100_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="p">[</span><span class="mi">180</span><span class="p">,</span> <span class="mi">100</span><span class="p">])</span> <span class="p">)</span> <span class="n">s100ms110_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">max_size</span><span class="o">=</span><span class="mi">110</span><span class="p">)</span> <span class="p">)</span> <span class="n">sNonems110_data</span> <span class="o">=</span> <span class="nc">OxfordIIITPet</span><span class="p">(</span> <span class="n">root</span><span class="o">=</span><span class="sh">"</span><span class="s">data</span><span class="sh">"</span><span class="p">,</span> <span class="n">transform</span><span class="o">=</span><span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">max_size</span><span class="o">=</span><span class="mi">110</span><span class="p">)</span> <span class="p">)</span> <span class="kn">import</span> <span class="n">matplotlib.pyplot</span> <span class="k">as</span> <span class="n">plt</span> <span class="k">def</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span> <span class="n">plt</span><span class="p">.</span><span class="nf">suptitle</span><span class="p">(</span><span class="n">t</span><span class="o">=</span><span class="n">main_title</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mf">0.8</span><span class="p">,</span> <span class="n">fontsize</span><span class="o">=</span><span class="mi">14</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="p">(</span><span class="n">im</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> <span class="nf">zip</span><span class="p">(</span><span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">6</span><span class="p">),</span> <span class="n">data</span><span class="p">):</span> <span class="n">plt</span><span class="p">.</span><span class="nf">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="n">im</span><span class="p">)</span> <span class="n">plt</span><span class="p">.</span><span class="nf">tight_layout</span><span class="p">()</span> <span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">origin_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">s1000_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s1000_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">s100_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">s50_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s50_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">s10_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s10_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">print</span><span class="p">()</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">origin_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">s100_180_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100_180_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">s180_100_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s180_100_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">print</span><span class="p">()</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">s100_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">s100ms110_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100ms110_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images1</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">sNonems110_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">sNonems110_data</span><span class="sh">"</span><span class="p">)</span> <span class="c1"># ↓ ↓ ↓ ↓ ↓ ↓ The code below is identical to the code above. ↓ ↓ ↓ ↓ ↓ ↓ </span><span class="k">def</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="bp">None</span><span class="p">,</span> <span class="n">ms</span><span class="o">=</span><span class="bp">None</span><span class="p">):</span> <span class="n">plt</span><span class="p">.</span><span class="nf">figure</span><span class="p">(</span><span class="n">figsize</span><span class="o">=</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span> <span class="mi">5</span><span class="p">))</span> <span class="n">plt</span><span class="p">.</span><span class="nf">suptitle</span><span class="p">(</span><span class="n">t</span><span class="o">=</span><span class="n">main_title</span><span class="p">,</span> <span class="n">y</span><span class="o">=</span><span class="mf">0.8</span><span class="p">,</span> <span class="n">fontsize</span><span class="o">=</span><span class="mi">14</span><span class="p">)</span> <span class="n">temp_s</span> <span class="o">=</span> <span class="n">s</span> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="p">(</span><span class="n">im</span><span class="p">,</span> <span class="n">_</span><span class="p">)</span> <span class="ow">in</span> <span class="nf">zip</span><span class="p">(</span><span class="nf">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">6</span><span class="p">),</span> <span class="n">data</span><span class="p">):</span> <span class="n">plt</span><span class="p">.</span><span class="nf">subplot</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">5</span><span class="p">,</span> <span class="n">i</span><span class="p">)</span> <span class="k">if</span> <span class="ow">not</span> <span class="n">temp_s</span> <span class="ow">and</span> <span class="ow">not</span> <span class="n">ms</span><span class="p">:</span> <span class="n">s</span> <span class="o">=</span> <span class="p">[</span><span class="n">im</span><span class="p">.</span><span class="n">size</span><span class="p">[</span><span class="mi">1</span><span class="p">],</span> <span class="n">im</span><span class="p">.</span><span class="n">size</span><span class="p">[</span><span class="mi">0</span><span class="p">]]</span> <span class="n">resize</span> <span class="o">=</span> <span class="nc">Resize</span><span class="p">(</span><span class="n">size</span><span class="o">=</span><span class="n">s</span><span class="p">,</span> <span class="n">max_size</span><span class="o">=</span><span class="n">ms</span><span class="p">)</span> <span class="c1"># Here </span> <span class="n">plt</span><span class="p">.</span><span class="nf">imshow</span><span class="p">(</span><span class="n">X</span><span class="o">=</span><span class="nf">resize</span><span class="p">(</span><span class="n">im</span><span class="p">))</span> <span class="c1"># Here </span> <span class="n">plt</span><span class="p">.</span><span class="nf">tight_layout</span><span class="p">()</span> <span class="n">plt</span><span class="p">.</span><span class="nf">show</span><span class="p">()</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">origin_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s1000_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">1000</span><span class="p">)</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">50</span><span class="p">)</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s10_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">10</span><span class="p">)</span> <span class="nf">print</span><span class="p">()</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">origin_data</span><span class="sh">"</span><span class="p">)</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100_180_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="p">[</span><span class="mi">100</span><span class="p">,</span> <span class="mi">180</span><span class="p">])</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s180_100_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="p">[</span><span class="mi">180</span><span class="p">,</span> <span class="mi">100</span><span class="p">])</span> <span class="nf">print</span><span class="p">()</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">)</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">s100ms110_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">s</span><span class="o">=</span><span class="mi">100</span><span class="p">,</span> <span class="n">ms</span><span class="o">=</span><span class="mi">110</span><span class="p">)</span> <span class="nf">show_images2</span><span class="p">(</span><span class="n">data</span><span class="o">=</span><span class="n">origin_data</span><span class="p">,</span> <span class="n">main_title</span><span class="o">=</span><span class="sh">"</span><span class="s">sNonems110_data</span><span class="sh">"</span><span class="p">,</span> <span class="n">ms</span><span class="o">=</span><span class="mi">110</span><span class="p">)</span> </code></pre> </div> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhg15nzsxt1f66pgc44qj.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhg15nzsxt1f66pgc44qj.png" alt="Image description" width="800" height="246"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagjqxj3l50sdu8vm5kgq.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fagjqxj3l50sdu8vm5kgq.png" alt="Image description" width="800" height="242"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnb1z7y0lxhua7815oyc.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnb1z7y0lxhua7815oyc.png" alt="Image description" width="800" height="247"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4470kz8iagsn7je6abt.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fw4470kz8iagsn7je6abt.png" alt="Image description" width="800" height="250"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flyps10ek5pvj1xbfzt3j.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flyps10ek5pvj1xbfzt3j.png" alt="Image description" width="800" height="247"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhg15nzsxt1f66pgc44qj.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhg15nzsxt1f66pgc44qj.png" alt="Image description" width="800" height="246"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0439dnavmba8g17tp8r.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp0439dnavmba8g17tp8r.png" alt="Image description" width="800" height="206"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1dkhuq02blajaqysyv0.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp1dkhuq02blajaqysyv0.png" alt="Image description" width="800" height="278"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnb1z7y0lxhua7815oyc.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqnb1z7y0lxhua7815oyc.png" alt="Image description" width="800" height="247"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1x5pqnzh16qjnypbr2rj.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1x5pqnzh16qjnypbr2rj.png" alt="Image description" width="800" height="247"></a></p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u2qqzt6dmftj0uajh6q.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6u2qqzt6dmftj0uajh6q.png" alt="Image description" width="800" height="247"></a></p>

Lire l'article Ouvrir Resize in PyTorch dans un nouvel onglet
How to Use cURL With Proxy

How to Use cURL With Proxy

21 janvier 2025

<p>This blog was initially posted to <a href="https://crawlbase.com/blog/how-to-use-curl-with-proxy/?utm_source=dev.to&amp;utm_medium=referral&amp;utm_campaign=content_distribution">Crawlbase Blog</a></p> <p>Using a proxy with cURL is a great way to manage web requests, hide your IP, and bypass network restrictions. Whether you’re web scraping, testing APIs or securing your internet traffic, proxies help by hiding your real IP and routing requests through a different server.</p> <p><strong>But first, what is cURL?</strong></p> <p><strong>cURL</strong> (short for Client URL) is a command line tool to send and receive data using various network protocols like HTTP, HTTPS, FTP, and more. It’s a small but powerful tool used by developers to test, automate web requests, and fetch data from endpoints.</p> <p>Here’s everything you need to know about using cURL with proxies. Installing cURL on different platforms, setting up HTTP, HTTPS, and SOCKS proxies, environment variables, persistent proxy settings, and how to bypass proxies. Let’s go!</p> <h2> Why Use cURL With a Proxy? </h2> <p>Using a proxy with cURL is great for anyone working with web requests. A proxy is an intermediate layer between your computer and the internet; it sends your requests through its server. Here’s why proxies with cURL are so cool:</p> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfcyma6u16pscnw4pwv8.jpg" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhfcyma6u16pscnw4pwv8.jpg" alt="Why use cURL with a Proxy" width="800" height="480"></a></p> <ol> <li> <strong>Enhanced Privacy</strong> Proxies hide your real IP address and replace it with theirs. So you stay anonymous while sending requests and safe online.</li> <li> <strong>Access Restricted Content</strong> Proxies help you avoid geographical restrictions or firewalls so you can access websites and data that would otherwise be blocked.</li> <li> <strong>Avoid Rate Limits &amp; IP Bans</strong> When doing scraping or API testing, proxies allow you to rotate IPs so websites won’t block your requests.</li> <li> <strong>Network Efficiency</strong> Some proxy servers use caching which minimize the time needed to complete requests, overall performance will be better.</li> </ol> <p>Whether you’re testing APIs, scraping web data or securely accessing the internet, using cURL with a proxy is a simple solution for your needs. In the next sections, we’ll show you how to set up and use cURL with different types of proxies.</p> <h2> Installing cURL on Different Platforms </h2> <p>Before you can use cURL with a proxy you need to make sure cURL is installed on your system. Here’s how to install cURL on Windows, macOS, and Linux.</p> <h3> For Windows </h3> <ol> <li>Go to the cURL download page: curl.se/windows.</li> <li>Download the correct version for your system (32-bit or 64-bit).</li> <li>Extract the ZIP file.</li> <li>Add the curl.exe to your system’s PATH so you can use it from the command prompt.</li> </ol> <p>To test the installation, run:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--version</span> </code></pre> </div> <h3> For macOS </h3> <p>cURL is included with most macOS systems. To check if it’s installed, open the Terminal and type:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--version</span> </code></pre> </div> <p>If it’s not installed or you want the latest version, use Homebrew:</p> <ol> <li>Install Homebrew if it’s not already installed: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>/bin/bash <span class="nt">-c</span> <span class="s2">"</span><span class="si">$(</span>curl <span class="nt">-fsSL</span> https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh<span class="si">)</span><span class="s2">"</span> </code></pre> </div> <ol> <li>Install cURL: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>brew <span class="nb">install </span>curl </code></pre> </div> <h3> For Linux </h3> <p>Many Linux distributions include cURL by default. To check, open the terminal and run:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--version</span> </code></pre> </div> <p>If it’s not installed, you can easily install it depending on your distribution:</p> <ul> <li> <strong>Ubuntu/Debian:</strong> </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">sudo </span>apt update <span class="nb">sudo </span>apt <span class="nb">install </span>curl </code></pre> </div> <ul> <li> <strong>CentOS/Fedora:</strong> </li> </ul> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">sudo </span>yum <span class="nb">install </span>curl </code></pre> </div> <p>Once installed, verify by running:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--version</span> </code></pre> </div> <p>Now that you have cURL installed, let’s move on to using cURL with HTTP and HTTPS proxies.</p> <h2> Using cURL With HTTP/HTTPS Proxy </h2> <p>Proxies are used to add privacy, bypass network restrictions, and scraping tasks. cURL makes it easy to work with HTTP and HTTPS proxies by allowing you to route your requests through a proxy server.</p> <h3> Basic Syntax for HTTP Proxy </h3> <p>To use an HTTP proxy with cURL you need to use the <code>-x</code> or <code>--proxy</code> option. Here’s the basic syntax:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">-x</span> <span class="s2">"http://proxy_address:port"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <ul> <li>Replace <code>proxy_address</code> with the proxy server’s address.</li> <li>Replace <code>port</code> with the proxy’s port number.</li> <li>Replace <code>http://example.com</code> with the URL you want to access.</li> </ul> <p><strong>Example:</strong></p> <p>If your proxy address is <code>127.0.0.1</code> and the port is <code>8080</code>, the command would look like this:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">-x</span> <span class="s2">"http://127.0.0.1:8080"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <h3> Example of HTTPS Proxy </h3> <p>When using HTTPS proxies, the process is similar. You need to specify the HTTPS protocol in the proxy address:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--proxy</span> <span class="s2">"https://proxy_address:port"</span> <span class="s2">"https://example.com"</span> </code></pre> </div> <p><strong>Example:</strong></p> <p>Suppose your HTTPS proxy address is <code>proxy.example.com</code>, and the port is <code>443</code>. The command would be:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--proxy</span> <span class="s2">"https://proxy.example.com:443"</span> <span class="s2">"https://secure-site.com"</span> </code></pre> </div> <h3> Adding Authentication </h3> <p>If your proxy requires a username and password, you can include them in the command:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">-x</span> <span class="s2">"http://username:password@proxy_address:port"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <p><strong>Example:</strong></p> <p>For a proxy at <code>127.0.0.1:8080</code> with a username of <code>user</code> and a password of <code>pass</code>, the command would be:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">-x</span> <span class="s2">"http://user:pass@127.0.0.1:8080"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <h3> Handling SSL Certificate Errors </h3> <p>When using HTTPS proxies, you might encounter SSL certificate errors. To bypass them (if you trust the proxy server) use the <code>-k</code> option:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--proxy</span> <span class="s2">"https://proxy.example.com:443"</span> <span class="s2">"https://secure-site.com"</span> <span class="nt">-k</span> </code></pre> </div> <p>Using cURL with HTTP and HTTPS proxies hides your IP and allows you to access restricted websites. Next, we’ll use cURL with SOCKS proxies.</p> <h2> Using cURL With SOCKS Proxy </h2> <p>A SOCKS proxy is a lower-level proxy than HTTP and HTTPS proxies. It works with more types of traffic, including FTP and others. cURL supports SOCKS proxies so it’s great for web scraping or bypassing geo-restrictions.</p> <h3> Basic Syntax for SOCKS Proxy </h3> <p>To use a SOCKS proxy with cURL you can use the <code>-x</code> or <code>--proxy</code> option just like with HTTP/HTTPS proxies. The only difference is specifying the SOCKS protocol (SOCKS4 or SOCKS5). The basic syntax is:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">-x</span> <span class="s2">"socks5://proxy_address:port"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <ul> <li>Replace <code>proxy_address</code> with the SOCKS proxy server address.</li> <li>Replace <code>port</code> with the proxy port number.</li> <li>Replace <code>http://example.com</code> with the URL you want to visit.</li> </ul> <p><strong>Example:</strong></p> <p>If you are using a SOCKS5 proxy at <code>127.0.0.1</code> and the port is <code>1080</code>, the command will be:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">-x</span> <span class="s2">"socks5://127.0.0.1:1080"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <h3> Authentication with SOCKS Proxy </h3> <p>Some SOCKS proxies require authentication, just like HTTP/HTTPS proxies. To add a username and password for authentication, you can include them in the proxy URL:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">-x</span> <span class="s2">"socks5://username:password@proxy_address:port"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <p><strong>Example:</strong></p> <p>For a SOCKS5 proxy at <code>127.0.0.1</code> on port <code>1080</code> with username user and password pass, the command will be:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">-x</span> <span class="s2">"socks5://user:pass@127.0.0.1:1080"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <h3> Using <code>--socks</code> Option </h3> <p>In addition to the -x option, you can use <code>--socks5</code> (or <code>--socks4</code> for SOCKS4) to specify the proxy protocol explicitly. Here’s the syntax for SOCKS5:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--socks5</span> <span class="s2">"127.0.0.1:1080"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <p>This approach is especially useful if you want to avoid confusion when working with multiple types of proxies.</p> <p>Using SOCKS proxies with cURL is great when you need more flexibility and want to route different types of traffic, including FTP and others. In the next section, we’ll cover how to set up proxy settings using environment variables.</p> <h2> Setting Proxy Using Environment Variables </h2> <p>You can set a proxy for cURL using environment variables, which is useful for applying the same proxy to multiple cURL commands.</p> <h3> For HTTP and HTTPS </h3> <p>To set the proxy for HTTP and HTTPS requests, use these commands in your terminal:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">export </span><span class="nv">http_proxy</span><span class="o">=</span><span class="s2">"http://user:password@proxy_address:port"</span> <span class="nb">export </span><span class="nv">https_proxy</span><span class="o">=</span><span class="s2">"http://user:password@proxy_address:port"</span> </code></pre> </div> <ul> <li>Replace <code>user:password</code> with your proxy credentials.</li> <li>Replace <code>proxy_address</code> with the IP or domain of the proxy server.</li> <li>Replace <code>port</code> with the proxy's port number.</li> </ul> <p><strong>Example:</strong><br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">export </span><span class="nv">http_proxy</span><span class="o">=</span><span class="s2">"http://user:pass@127.0.0.1:1080"</span> <span class="nb">export </span><span class="nv">https_proxy</span><span class="o">=</span><span class="s2">"http://user:pass@127.0.0.1:1080"</span> </code></pre> </div> <h3> How to Unset Proxy Variables </h3> <p>To stop using the proxy, run these commands:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">unset </span>http_proxy <span class="nb">unset </span>https_proxy </code></pre> </div> <p>This will remove the proxy settings for the current session.</p> <p>In the next section, we’ll cover how to configure cURL to always use a proxy.</p> <h2> Configuring cURL to Always Use a Proxy </h2> <p>If you want cURL to always use a proxy without needing to set it every time, you can configure it to do so by editing a configuration file.</p> <h3> For Linux and macOS </h3> <ol> <li>Open the terminal and go to your home directory: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">cd</span> ~ </code></pre> </div> <ol> <li> Check if you have a <code>.curlrc</code> file. If not, create one: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>nano .curlrc </code></pre> </div> <ol> <li> Add your proxy settings inside this file: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nv">proxy</span><span class="o">=</span><span class="s2">"http://user:password@proxy_address:port"</span> </code></pre> </div> <ol> <li> Save the file and exit. Now, cURL will use the proxy settings automatically for every request.</li> </ol> <h3> For Windows </h3> <p>On Windows, the configuration file is named <code>_curlrc</code> and is located in the <code>%APPDATA%</code> directory.</p> <ol> <li>Open the command prompt and run this command to find the path: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">echo</span> %APPDATA% </code></pre> </div> <ol> <li><p>Go to the directory path shown and create a file named <code>_curlrc</code>.</p></li> <li><p>Inside this file, add your proxy settings:<br> </p></li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nv">proxy</span><span class="o">=</span><span class="s2">"http://user:password@proxy_address:port"</span> </code></pre> </div> <ol> <li> Save the file, and cURL will use the proxy for all future requests.</li> </ol> <p>This method helps streamline your cURL usage and ensures your proxy is always set. In the next section, we’ll discuss how to ignore the proxy for specific requests.</p> <h2> Ignoring Proxy for Specific Requests </h2> <p>There may be times when you want to bypass the proxy for certain requests while using cURL. Fortunately, cURL offers an easy way to do this.</p> <h3> How to Ignore the Proxy </h3> <p>To bypass the proxy for a specific request, use the <code>--noproxy</code> option. This tells cURL not to use the proxy for the URL you specify. Here's how it works:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--noproxy</span> <span class="s2">"*"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <p>In this example, the <code>*</code> wildcard ensures that no proxy will be used for <code>http://example.com</code>. This is useful when you want to make direct connections to specific websites while keeping the proxy settings active for others.</p> <h3> Ignoring Proxy for Specific Domains </h3> <p>You can also ignore the proxy for specific domains or IP addresses. For instance, if you want to avoid using the proxy for domain <code>example.com</code>, you can set the <code>--noproxy</code> option like this:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="nt">--noproxy</span> <span class="s2">"example.com"</span> <span class="s2">"http://example.com"</span> </code></pre> </div> <p>This will not use the proxy for domain <code>example.com</code> but will use the proxy for other requests.</p> <p>Using the <code>--noproxy</code> flag you can control when to use the proxy and when to connect directly to a website. This is important for managing your network connections.</p> <p>In the next section, we’ll go over some quick tips for proxies.</p> <h2> Quick Proxy Management Tips </h2> <p>Managing proxies can save you time and effort if you switch between proxy configurations often. Here are some quick tips to help you manage proxies with cURL</p> <h3> 1. Turn Proxy On and Off Quickly </h3> <p>If you switch between using a proxy and not using one often you can create aliases in your shell configuration file. This way you can turn the proxy on and off with a single command. For example, you can add the following aliases to your <code>.bashrc</code> or <code>.zshrc</code> file:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">alias </span><span class="nv">proxyon</span><span class="o">=</span><span class="s2">"export http_proxy='http://user:pwd@127.0.0.1:1234'; export https_proxy='http://user:pwd@127.0.0.1:1234'"</span> <span class="nb">alias </span><span class="nv">proxyoff</span><span class="o">=</span><span class="s2">"unset http_proxy; unset https_proxy"</span> </code></pre> </div> <p>After saving the file, run:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">source</span> ~/.bashrc <span class="c"># or source ~/.zshrc</span> </code></pre> </div> <p>Now, you can quickly turn the proxy on by typing proxyon and turn it off by typing proxyoff. This makes it easy to switch proxy settings as needed.</p> <h3> 2. Use a Proxy for Specific URLs Only </h3> <p>If you want to use the proxy only for certain URLs, set the environment variables temporarily for that specific session.<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">export </span><span class="nv">http_proxy</span><span class="o">=</span><span class="s2">"http://user:pwd@127.0.0.1:1234"</span> curl <span class="s2">"http://example.com"</span> </code></pre> </div> <p>This command ensures that the proxy is used only for domain <code>example.com</code>. When you no longer need the proxy, simply unset the variables:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code><span class="nb">unset </span>http_proxy <span class="nb">unset </span>https_proxy </code></pre> </div> <h3> 3. Test Proxy Connection </h3> <p>It’s essential to test your proxy settings before using them in production. You can do this by running a simple cURL command to check the IP address:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>curl <span class="s2">"https://httpbin.org/ip"</span> </code></pre> </div> <p>If everything is set up correctly, you should see the IP address of the proxy server instead of your own.</p> <h2> Final Thoughts </h2> <p>Using a proxy with cURL is a powerful way to hide your privacy, manage traffic, and bypass restrictions. Whether you’re working with HTTP, HTTPS or SOCKS proxies, cURL makes it easy to route your requests through different servers. With the ability to set proxies using command line options, environment variable, or configuration files, you have full control over how your requests are handled.</p> <p>Follow this guide and you’ll be able to use cURL with proxies in your workflow in no time, perfect for web scraping, automation or even just simple API requests. Proxies help hide your IP and avoid geographical restrictions so are essential for many users who need secure and anonymous browsing. If you're looking for a proxy provider, you can choose Crawlbase's Smart Proxy service, one of the best in the market.</p> <p>Regardless of Linux, macOS, or Windows, the process is the same, and with the right setup you can manage your proxies. Always test your configuration regularly to make sure everything is working smoothly. Happy coding!</p> <h2> Frequently Asked Questions </h2> <h3> Q. What is a proxy in cURL? </h3> <p>A proxy in cURL is an intermediate server that sits between your computer and the internet. Using a proxy, cURL routes your requests through the proxy server instead of going directly to the website. This hides your real IP, improves privacy, and bypasses geographical restrictions.</p> <h3> Q. Can I use cURL with a SOCKS proxy? </h3> <p>Yes, you can use cURL with SOCKS proxies, like SOCKS4 or SOCKS5. Just add the right protocol to your cURL command, like <code>socks5://</code> for SOCKS5 proxies. This is helpful when working with network configurations that need SOCKS or while preserving anonymity.</p> <h3> Q. How do I set a default proxy for cURL? </h3> <p>You can set a default proxy for cURL using a configuration file. For Linux and macOS, create a <code>.curlrc</code> file in your home directory where you can put your proxy details. For Windows, it’s <code>_curlrc</code> in the <code>%APPDATA%</code> directory. This way cURL will always use the proxy without you needing to specify it in each command.</p>

Lire l'article Ouvrir How to Use cURL With Proxy dans un nouvel onglet
The DRY Principle in Programming: Why It’s Not Always the Best Approach

The DRY Principle in Programming: Why It’s Not Always the Best Approach

21 janvier 2025

<p>As developers, we’ve all heard of the DRY principle—“Don’t Repeat Yourself” principle. It’s one of the foundational concepts in programming that encourages reducing code duplication to make our programs more maintainable, efficient, and less error-prone. But here is the thing: While DRY is a valuable principle, there are times when following it too strictly can actually make our code complicated and reduce readability and harder to understand.</p> <p>In this blog post, we’ll understand when applying DRY might be wrong, and how to apply the right balance between reusing code and keeping it simple to understand.</p> <h2> <strong>🚀 Example 1: Greeting Message</strong> </h2> <p>Let us explore with a simple scenario:</p> <p>We have to create a greeting message for users based on the time of day. The message will change depending on whether it’s morning, afternoon, or evening.</p> <p><strong>Without DRY:</strong></p> <p>We will create three separate functions, one for each condition by keeping it simple and clear.</p> <p><strong>For example:</strong><br> </p> <div class="highlight js-code-highlight"> <pre class="highlight tsx"><code><span class="c1">// for morning</span> <span class="kd">function</span> <span class="nf">greetingMorningMessage</span><span class="p">(</span><span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span> <span class="k">return</span> <span class="s2">`Good morning, </span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// for afternoon</span> <span class="kd">function</span> <span class="nf">greetingAfternoonMessage</span><span class="p">(</span><span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span> <span class="k">return</span> <span class="s2">`Good afternoon, </span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span> <span class="p">}</span> <span class="c1">// for evening</span> <span class="kd">function</span> <span class="nf">greetingEveningMessage</span><span class="p">(</span><span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span> <span class="k">return</span> <span class="s2">`Good evening, </span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p>These functions are straightforward and each of them handles different cases.</p> <p><strong>Applying DRY:</strong></p> <p>Now, let us try to follow the DRY principle. We might decide to combine three different functions into a single function on the basis of an additional parameter called “<em>timeOfDay</em>.”</p> <p><strong>For example:</strong><br> </p> <div class="highlight js-code-highlight"> <pre class="highlight tsx"><code><span class="kd">type</span> <span class="nx">TimeOfDay</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">morning</span><span class="dl">'</span> <span class="o">|</span> <span class="dl">'</span><span class="s1">afternoon</span><span class="dl">'</span> <span class="o">|</span> <span class="dl">'</span><span class="s1">evening</span><span class="dl">'</span><span class="p">;</span> <span class="kd">function</span> <span class="nf">greetMessage</span><span class="p">(</span><span class="nx">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">,</span> <span class="nx">timeOfDay</span><span class="p">:</span> <span class="nx">TimeOfDay</span><span class="p">):</span> <span class="kr">string</span> <span class="p">{</span> <span class="k">if </span><span class="p">(</span><span class="nx">timeOfDay</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">morning</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="s2">`Good morning, </span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="k">if </span><span class="p">(</span><span class="nx">timeOfDay</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">afternoon</span><span class="dl">'</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="s2">`Good afternoon, </span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="s2">`Good evening, </span><span class="p">${</span><span class="nx">name</span><span class="p">}</span><span class="s2">!`</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </code></pre> </div> <p>Great, we didn’t repeat our code. But, <strong>did we simplify things?</strong></p> <p>📚 <strong>The Lesson:</strong></p> <p>The original approach (i.e., without the DRY principle) was clearer and more explicit. The DRY version is great, but it requires an extra parameter (i.e., “timeOfDay”) that might not be useful, and we have to pass it every time we call the function.</p> <p>Sometimes duplicating code for the sake of clarity can be the better approach, especially when the logic is simple and doesn’t need to be generalized.</p> <h2> <strong>🚀 Example 2: Age Calculation</strong> </h2> <p>Now, let us explore a simple scenario where applying DRY makes perfect sense. We will calculate the age of a person on the basis of their birth year. Let us consider there are two roles: students and teachers.</p> <p><strong>Without DRY:</strong></p> <p>We will write separate functions for each role:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight tsx"><code><span class="kr">interface</span> <span class="nx">Student</span> <span class="p">{</span> <span class="nl">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span> <span class="nl">birthYear</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span> <span class="p">}</span> <span class="kr">interface</span> <span class="nx">Teacher</span> <span class="p">{</span> <span class="nl">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span> <span class="nl">birthYear</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span> <span class="p">}</span> <span class="kd">function</span> <span class="nf">calculateStudentAge</span><span class="p">(</span><span class="nx">student</span><span class="p">:</span> <span class="nx">Student</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">currentYear</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Date</span><span class="p">().</span><span class="nf">getFullYear</span><span class="p">();</span> <span class="k">return</span> <span class="nx">currentYear</span> <span class="o">-</span> <span class="nx">student</span><span class="p">.</span><span class="nx">birthYear</span><span class="p">;</span> <span class="p">}</span> <span class="kd">function</span> <span class="nf">calculateTeacherAge</span><span class="p">(</span><span class="nx">teacher</span><span class="p">:</span> <span class="nx">Teacher</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">currentYear</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Date</span><span class="p">().</span><span class="nf">getFullYear</span><span class="p">();</span> <span class="k">return</span> <span class="nx">currentYear</span> <span class="o">-</span> <span class="nx">teacher</span><span class="p">.</span><span class="nx">birthYear</span><span class="p">;</span> <span class="p">}</span> </code></pre> </div> <p>Now, let us think, <strong>Can we combine these two functions into a single function?</strong></p> <ul> <li><em>“Yeah! We can. Let’s do it!”</em></li> </ul> <p><strong>Applying DRY:</strong><br> </p> <div class="highlight js-code-highlight"> <pre class="highlight tsx"><code><span class="kr">interface</span> <span class="nx">User</span> <span class="p">{</span> <span class="nl">name</span><span class="p">:</span> <span class="kr">string</span><span class="p">;</span> <span class="nl">birthYear</span><span class="p">:</span> <span class="kr">number</span><span class="p">;</span> <span class="p">}</span> <span class="kd">function</span> <span class="nf">calculateAge</span><span class="p">(</span><span class="nx">user</span><span class="p">:</span> <span class="nx">User</span><span class="p">):</span> <span class="kr">number</span> <span class="p">{</span> <span class="kd">const</span> <span class="nx">currentYear</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Date</span><span class="p">().</span><span class="nf">getFullYear</span><span class="p">();</span> <span class="k">return</span> <span class="nx">currentYear</span> <span class="o">-</span> <span class="nx">user</span><span class="p">.</span><span class="nx">birthYear</span><span class="p">;</span> <span class="p">}</span> <span class="kd">const</span> <span class="nx">student</span><span class="p">:</span> <span class="nx">User</span> <span class="o">=</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Anjan</span><span class="dl">'</span><span class="p">,</span> <span class="na">birthYear</span><span class="p">:</span> <span class="mi">2003</span> <span class="p">};</span> <span class="kd">const</span> <span class="nx">teacher</span><span class="p">:</span> <span class="nx">User</span> <span class="o">=</span> <span class="p">{</span> <span class="na">name</span><span class="p">:</span> <span class="dl">'</span><span class="s1">Sajak</span><span class="dl">'</span><span class="p">,</span> <span class="na">birthYear</span><span class="p">:</span> <span class="mi">2002</span> <span class="p">};</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">calculateAge</span><span class="p">(</span><span class="nx">student</span><span class="p">));</span> <span class="c1">// Student's age</span> <span class="nx">console</span><span class="p">.</span><span class="nf">log</span><span class="p">(</span><span class="nf">calculateAge</span><span class="p">(</span><span class="nx">teacher</span><span class="p">));</span> <span class="c1">// Teacher's age</span> </code></pre> </div> <p>📚 <strong>The Lesson:</strong></p> <p>Here, we applied the DRY principle, which simplifies our code by removing duplication. A single function can handle all user types, making our code simpler and increasing readability.</p> <h2> <strong>🎯 Conclusion:</strong> </h2> <p>The DRY principle is powerful and great, but it has its own drawbacks. Reusing code is great, but it shouldn’t affect <strong>clarity, simplicity, or flexibility</strong> of the code. There are definitely times when repeating code makes more sense rather than abstracting it.</p> <p><strong>So what is the key takeaway?</strong></p> <p>Balance is crucial. The DRY principle is used to reduce duplication of code, but don’t be afraid to duplicate code when it leads to simpler and cleaner code.</p> <p>In the end, programming is all about solving problems. Sometimes, repeating code might be the simplest solution and avoid unnecessary complexity and over-engineering. After all, clarity and simplicity always win.</p> <p>Have you over-engineered any solutions while trying to follow the DRY principle? Share your experience in the comments below! 👇</p>

Lire l'article Ouvrir The DRY Principle in Programming: Why It’s Not Always the Best Approach dans un nouvel onglet
Scale Docker without K8s or Swarm

Scale Docker without K8s or Swarm

21 janvier 2025

<p>Nowadays, nearly every project we build or encounter utilizes Dockerized containers. However, scaling these containers when traffic spikes is a challenge that not everyone understands.</p> <p>You might be familiar with Kubernetes or Docker Swarm as tools for container orchestration. While adopting Kubernetes is one thing, testing Kubernetes (K8s) locally presents unique challenges for developers. Nevertheless, gaining at least a foundational understanding of Kubernetes, pods, and how K8s can replace Docker Compose is crucial. I'll cover Kubernetes in a separate post, simplifying its implementation and providing guidance on how to use it effectively without unnecessary overhead.</p> <h3> What About Scaling Docker Without Kubernetes? </h3> <p>Let's focus on what can be achieved without Kubernetes. How do we scale Docker effectively?</p> <p><em>Assuming you are already familiar with Docker's architecture and functionality.</em></p> <p>In simple terms, you can scale a Docker service with a single command:<br> </p> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>docker service scale <span class="nv">api</span><span class="o">=</span>10 </code></pre> </div> <h3> But What About Handling Incoming Requests? </h3> <p>Once you scale the service, you might have questions like:</p> <ul> <li>How do you handle incoming requests?</li> <li>How are requests routed to different containers?</li> <li>What happens if one service instance gets overloaded with traffic?</li> </ul> <h4> The Solution: Load Balancer as a Service </h4> <p>We can introduce a load balancer to manage traffic and distribute requests across scaled services using a round-robin or similar strategy.</p> <p>Here’s how to configure it using Docker Compose with NGINX as the load balancer.</p> <h4> Docker Compose Configuration </h4> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>version: <span class="s2">"3.9"</span> services: api: <span class="c"># Container name is omitted for scalability; Docker assigns dynamic names.</span> build: <span class="nb">.</span> <span class="c"># No ports are mapped here as Docker manages ports internally for scaled services.</span> nginx: image: nginx:latest volumes: - ./conf.d:/etc/nginx/conf.d depends_on: - api ports: - 3000:3000 </code></pre> </div> <h3> How NGINX Works in This Setup </h3> <p>The nginx service will handle traffic routing through its configuration file. Here's an example:</p> <h4> NGINX Configuration (conf.d/default.conf) </h4> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code>server <span class="o">{</span> listen 3000<span class="p">;</span> location / <span class="o">{</span> proxy_pass http://api:3000<span class="p">;</span> <span class="o">}</span> <span class="o">}</span> </code></pre> </div> <p>This configuration proxies all incoming traffic on port 3000 to the api service. Since we've scaled the api service to multiple instances, NGINX will distribute the traffic across them.</p> <h3> Key Considerations: </h3> <ul> <li><p>Dynamic Port Mapping:<br> We didn't expose ports for the api service in the docker-compose.yml file. This is intentional because scaled services share the same container port internally, and Docker handles dynamic port assignment. NGINX, mapped to a single external port, manages routing to the internal services.</p></li> <li><p>Round-Robin Traffic Distribution:<br> By default, NGINX distributes traffic in a round-robin manner. This ensures no single instance gets overwhelmed.</p></li> </ul> <p>And there you have it! You've successfully scaled your API service while ensuring balanced traffic distribution using NGINX as a load balancer. With this setup, scaling Docker services without Kubernetes becomes simple and efficient.</p> <p>Cheers! Happy Coding </p>

Lire l'article Ouvrir Scale Docker without K8s or Swarm dans un nouvel onglet
Using React with Astro: A Quick Tutorial

Using React with Astro: A Quick Tutorial

21 janvier 2025

<p>Hey there! If you love <a href="https://react.dev/" rel="noopener noreferrer">React</a> and want to try out a faster, lighter way to build websites, then Astro has you covered. <a href="https://astro.build/" rel="noopener noreferrer">Astro</a> makes it easy to use React components within its static-first framework. </p> <p>In this post, I’ll show you how to integrate React into an Astro project and build a cool interactive app to get you started.</p> <h2> Why Use React with Astro? </h2> <p>Astro’s biggest strength is its static-first approach, but sometimes you need that React magic for dynamic interactivity. Here’s why combining React with Astro can be a winning combo:</p> <ul> <li> <strong>Best of both worlds</strong>: Retain use of Astro’s lightweight performance while keeping React’s powerful component-based system for interactive features.</li> <li> <strong>Selective hydration</strong>: Astro lets you load React components only when they’re needed, saving bandwidth and speeding up your site.</li> <li> <strong>Easy integration</strong>: Adding React to Astro is simple and intuitive—you don’t have to rewrite your React components.</li> </ul> <h2> Let’s Build a React-Powered Counter in Astro </h2> <p>You're here for a demo. Let’s get started! We’re going to build a simple counter app using React within an Astro project. </p> <p>Here’s how:</p> <h3> Step 1: Create a New Astro Project </h3> <ol> <li>Start by setting up a fresh Astro project. Follow the prompts and you want to start in this dir <code>.</code> and you want a fresh starter app: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> <span class="nb">mkdir </span>astro-land <span class="o">&amp;&amp;</span> <span class="nb">cd </span>astro-land npm create astro@latest </code></pre> </div> <ol> <li>Add React support to your project. Follow the prompts. Astro makes it super easy: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> npx astro add react </code></pre> </div> <h3> Step 2: Build the Counter Component </h3> <ol> <li>Create a React component for the counter. In <code>src/components/Counter.jsx</code>, add this: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight jsx"><code> <span class="k">import</span> <span class="p">{</span> <span class="nx">useState</span> <span class="p">}</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">react</span><span class="dl">'</span><span class="p">;</span> <span class="kd">function</span> <span class="nf">Counter</span><span class="p">()</span> <span class="p">{</span> <span class="kd">const</span> <span class="p">[</span><span class="nx">count</span><span class="p">,</span> <span class="nx">setCount</span><span class="p">]</span> <span class="o">=</span> <span class="nf">useState</span><span class="p">(</span><span class="mi">0</span><span class="p">);</span> <span class="k">return </span><span class="p">(</span> <span class="p">&lt;</span><span class="nt">div</span> <span class="na">style</span><span class="p">=</span><span class="si">{</span><span class="p">{</span> <span class="na">textAlign</span><span class="p">:</span> <span class="dl">'</span><span class="s1">center</span><span class="dl">'</span> <span class="p">}</span><span class="si">}</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">h2</span><span class="p">&gt;</span>Counter: <span class="si">{</span><span class="nx">count</span><span class="si">}</span><span class="p">&lt;/</span><span class="nt">h2</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="p">()</span> <span class="o">=&gt;</span> <span class="nf">setCount</span><span class="p">(</span><span class="nx">count</span> <span class="o">+</span> <span class="mi">1</span><span class="p">)</span><span class="si">}</span><span class="p">&gt;</span>Increase<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">button</span> <span class="na">onClick</span><span class="p">=</span><span class="si">{</span><span class="p">()</span> <span class="o">=&gt;</span> <span class="nf">setCount</span><span class="p">(</span><span class="nx">count</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span><span class="si">}</span><span class="p">&gt;</span>Decrease<span class="p">&lt;/</span><span class="nt">button</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">div</span><span class="p">&gt;</span> <span class="p">);</span> <span class="p">}</span> <span class="k">export</span> <span class="k">default</span> <span class="nx">Counter</span><span class="p">;</span> </code></pre> </div> <h3> Step 3: Use the Counter in an Astro Page </h3> <ol> <li>Open or create <code>src/pages/index.astro</code> and import the <code>Counter</code> component: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight jsx"><code> <span class="o">---</span> <span class="k">import</span> <span class="nx">Counter</span> <span class="k">from</span> <span class="dl">'</span><span class="s1">../components/Counter.jsx</span><span class="dl">'</span><span class="p">;</span> <span class="o">---</span> <span class="p">&lt;</span><span class="nt">html</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">head</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">title</span><span class="p">&gt;</span>React in Astro<span class="p">&lt;/</span><span class="nt">title</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">head</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">body</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nt">h1</span> <span class="na">style</span><span class="p">=</span><span class="si">{</span><span class="p">{</span> <span class="na">textAlign</span><span class="p">:</span> <span class="dl">'</span><span class="s1">center</span><span class="dl">'</span> <span class="p">}</span><span class="si">}</span><span class="p">&gt;</span>Welcome to Astro + React<span class="p">&lt;/</span><span class="nt">h1</span><span class="p">&gt;</span> <span class="p">&lt;</span><span class="nc">Counter</span> <span class="na">client</span><span class="err">:</span><span class="na">load</span> <span class="p">/&gt;</span> <span class="p">&lt;/</span><span class="nt">body</span><span class="p">&gt;</span> <span class="p">&lt;/</span><span class="nt">html</span><span class="p">&gt;</span> </code></pre> </div> <p>Here’s the magic: the <code>client:load</code> directive tells Astro to hydrate this component on the client side, making it interactive.</p> <h3> Step 4: Run and See the Magic </h3> <ol> <li>Start the development server: </li> </ol> <div class="highlight js-code-highlight"> <pre class="highlight shell"><code> npm run dev </code></pre> </div> <ol> <li>Open your browser and navigate to <code>http://localhost:4321</code>. Click those buttons, and watch your counter work like a charm!</li> </ol> <p><a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdd0gns4tq5of4qtflg75.png" class="article-body-image-wrapper"><img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdd0gns4tq5of4qtflg75.png" alt="Image description" width="800" height="447"></a></p> <h2> Selective Hydration: Why It’s Awesome </h2> <p>One of Astro’s coolest features is selective hydration. Unlike traditional frameworks that load all JavaScript upfront, Astro only hydrates the components that need interactivity. This means your site stays fast and snappy, even as you add more dynamic elements.</p> <p>In our example, only the <code>Counter</code> component gets hydrated, while the rest of the page is just static HTML.</p> <h2> Final Thoughts </h2> <p>Using React with Astro is a game-changer for building high-performance websites with just the right amount of interactivity. Whether you’re building a blog, a portfolio, or a complex app, this combo gives you the tools to create something awesome.</p> <p>So go ahead, give Astro + React a spin, and let me know what you think. Happy coding!</p> <p>Comment below if this helped or if you'd like to see more tutorials on React + Astro. For example, integrating more complicated components with props, adding other frameworks like <a href="https://tailwindcss.com/" rel="noopener noreferrer">Tailwind</a> and more!</p>

Lire l'article Ouvrir Using React with Astro: A Quick Tutorial dans un nouvel onglet