<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Solomon Eseme</title>
    <description>The latest articles on Forem by Solomon Eseme (@kaperskyguru).</description>
    <link>https://forem.com/kaperskyguru</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F56229%2Fe031c2a2-cd76-404a-b547-e26e04507c1c.jpg</url>
      <title>Forem: Solomon Eseme</title>
      <link>https://forem.com/kaperskyguru</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kaperskyguru"/>
    <language>en</language>
    <item>
      <title>Backend Developer Resume Writing: The Ultimate Guide</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Sun, 25 May 2025 09:28:12 +0000</pubDate>
      <link>https://forem.com/masteringbackend/backend-developer-resume-writing-the-ultimate-guide-lb8</link>
      <guid>https://forem.com/masteringbackend/backend-developer-resume-writing-the-ultimate-guide-lb8</guid>
      <description>&lt;p&gt;If you’re looking to land your next backend developer role, one of the most important tools in your job search is a strong resume.&lt;/p&gt;

&lt;p&gt;Whether you’re just getting started as a &lt;strong&gt;junior backend developer&lt;/strong&gt; or you’re an experienced &lt;strong&gt;backend engineer&lt;/strong&gt; looking to make a move, your resume needs to reflect the skills and experience that will grab a recruiter’s attention.&lt;/p&gt;

&lt;p&gt;In this guide, we’ll walk you through everything you need to know to write a &lt;strong&gt;backend developer resume&lt;/strong&gt; that stands out.&lt;/p&gt;

&lt;p&gt;From showcasing your technical skills to highlighting your key projects, we’ll cover the essential sections and tips to make sure your resume gets noticed by hiring managers.&lt;/p&gt;

&lt;p&gt;Let’s jump in and help you create a backend developer resume that opens doors to your next job!&lt;/p&gt;

&lt;h3&gt;
  
  
  Who is a Backend Developer?
&lt;/h3&gt;

&lt;p&gt;Before we dive into the resume tips, let’s quickly understand what a backend developer does. Simply put:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A backend developer builds and maintains the “behind-the-scenes” parts of a website or app.&lt;/li&gt;
&lt;li&gt;They work with servers, databases, and application logic.&lt;/li&gt;
&lt;li&gt;Think of them as the people who make sure everything works smoothly behind the curtain while the frontend developer makes the website look good and be user-friendly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you want to work with databases, APIs, server-side programming, and business logic, backend development is for you.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Is Your Resume So Important?
&lt;/h3&gt;

&lt;p&gt;Your resume is your first impression. It’s the document that opens the door to your next job. If your resume is boring, messy, or missing key details, you’ll get overlooked no matter how talented you are.&lt;/p&gt;

&lt;p&gt;A good backend developer resume will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Show your skills clearly and confidently.&lt;/li&gt;
&lt;li&gt;Highlight your experience and projects.&lt;/li&gt;
&lt;li&gt;Prove you understand the tools and technologies companies need.&lt;/li&gt;
&lt;li&gt;Make recruiters want to invite you for an interview.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How to Write a Backend Developer Resume: Step-by-Step
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. Choose the Right Resume Format
&lt;/h4&gt;

&lt;p&gt;There are three main resume formats:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Chronological:&lt;/strong&gt; Lists your work experience starting with the most recent. Best if you have steady experience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Functional:&lt;/strong&gt; Focuses on skills rather than work history. Good if you’re switching careers or have gaps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Combination:&lt;/strong&gt; Mix of both, showing skills and work experience.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For backend developers, chronological or combination resumes usually work best because you want to highlight your technical skills and your relevant work history.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Start with a Strong Resume Header
&lt;/h4&gt;

&lt;p&gt;At the very top, include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your full name&lt;/li&gt;
&lt;li&gt;Your professional title (e.g., Backend Developer, Software Engineer)&lt;/li&gt;
&lt;li&gt;Contact info: phone number, email, LinkedIn profile, GitHub (very important!)&lt;/li&gt;
&lt;li&gt;Location (city and state or just country is fine)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;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%2F9axzwop2svkuj5pjj8q0.png" class="article-body-image-wrapper"&gt;&lt;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%2F9axzwop2svkuj5pjj8q0.png" alt="resume writing" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Write a Clear and Concise Summary or Objective
&lt;/h4&gt;

&lt;p&gt;This is a short paragraph (2–4 sentences) summarizing who you are and what you bring to the table.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you have experience, write a &lt;strong&gt;Summary&lt;/strong&gt; focusing on your skills and achievements.&lt;/li&gt;
&lt;li&gt;If you’re new, write an &lt;strong&gt;Objective&lt;/strong&gt; focusing on your goals and eagerness to learn.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example Summary for Experienced Dev:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;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%2Fhjamqqe2a9h440jt1iuj.png" class="article-body-image-wrapper"&gt;&lt;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%2Fhjamqqe2a9h440jt1iuj.png" alt="resume writing" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example Objective for New Dev:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;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%2Fwq31ljphomib13dre87m.png" class="article-body-image-wrapper"&gt;&lt;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%2Fwq31ljphomib13dre87m.png" alt="resume writing" width="800" height="99"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Highlight Your Technical Skills
&lt;/h4&gt;

&lt;p&gt;This is a must-have section. List the programming languages, frameworks, tools, and technologies you know that are relevant to backend development.&lt;/p&gt;

&lt;p&gt;Group your skills to make it easy to read:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Languages:&lt;/strong&gt; Java, Python, C#, JavaScript (Node.js)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Databases:&lt;/strong&gt; MySQL, PostgreSQL, MongoDB&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frameworks:&lt;/strong&gt; Express.js, Spring Boot, Django&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tools:&lt;/strong&gt; Docker, Git, Jenkins&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cloud:&lt;/strong&gt; AWS, Azure, Google Cloud&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Make sure you tailor this list for each job application based on the job description.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;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%2Fjada47tmhqa69oj2tiui.png" class="article-body-image-wrapper"&gt;&lt;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%2Fjada47tmhqa69oj2tiui.png" alt="resume writing" width="800" height="125"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Show Off Your Work Experience
&lt;/h4&gt;

&lt;p&gt;This is the heart of your resume. For each job or project, include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Job title&lt;/li&gt;
&lt;li&gt;Company name and location&lt;/li&gt;
&lt;li&gt;Dates of employment&lt;/li&gt;
&lt;li&gt;Bullet points describing your responsibilities and achievements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use &lt;strong&gt;action verbs&lt;/strong&gt; and focus on results. Whenever possible, add numbers to show impact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;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%2Fgzn5ktn1w4a1kholt7gz.png" class="article-body-image-wrapper"&gt;&lt;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%2Fgzn5ktn1w4a1kholt7gz.png" alt="resume writing" width="800" height="641"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Include Projects (Especially if You’re a Beginner)
&lt;/h4&gt;

&lt;p&gt;If you don’t have much professional experience, projects are a great way to show your skills.&lt;/p&gt;

&lt;p&gt;List:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Project name&lt;/li&gt;
&lt;li&gt;Technologies used&lt;/li&gt;
&lt;li&gt;A short description of what you built or achieved&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;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%2Fcdhstuk98wtaf6obensi.png" class="article-body-image-wrapper"&gt;&lt;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%2Fcdhstuk98wtaf6obensi.png" alt="resume writing" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  7. Education Section
&lt;/h4&gt;

&lt;p&gt;List your degrees or certifications relevant to backend development.&lt;/p&gt;

&lt;p&gt;Include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Degree or certification name&lt;/li&gt;
&lt;li&gt;School or institution&lt;/li&gt;
&lt;li&gt;Graduation year (or expected graduation year)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;&lt;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%2Fndomejkz8vy61lu9pzqr.png" class="article-body-image-wrapper"&gt;&lt;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%2Fndomejkz8vy61lu9pzqr.png" alt="resume writing" width="800" height="82"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  8. Add Optional Sections
&lt;/h4&gt;

&lt;p&gt;Depending on your background, you can add extra sections like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Certifications:&lt;/strong&gt; AWS, Google Cloud, Microsoft Azure, Docker&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open Source Contributions:&lt;/strong&gt; If you contribute to GitHub projects&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Languages:&lt;/strong&gt; If you speak other languages fluently&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Awards and Honors&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tips to Make Your Backend Developer Resume Stand Out
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Use Keywords from the Job Description
&lt;/h4&gt;

&lt;p&gt;Many companies use &lt;strong&gt;Applicant Tracking Systems (ATS)&lt;/strong&gt; to scan resumes for keywords that match the job description. If your resume doesn’t include the right keywords, it might get overlooked.&lt;/p&gt;

&lt;p&gt;So, &lt;strong&gt;always read the job description carefully&lt;/strong&gt; and make sure to incorporate relevant keywords into your resume naturally.&lt;/p&gt;

&lt;p&gt;For example, if the job asks for experience with &lt;strong&gt;Node.js, PostgreSQL&lt;/strong&gt; , or &lt;strong&gt;AWS&lt;/strong&gt; , make sure these technologies are mentioned if you’ve worked with them.&lt;/p&gt;

&lt;h4&gt;
  
  
  Keep It Clear and Simple
&lt;/h4&gt;

&lt;p&gt;Recruiters and hiring managers often skim through hundreds of resumes in a short amount of time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keep your resume concise&lt;/strong&gt; and to the point. Avoid large blocks of text, &lt;strong&gt;use bullet points&lt;/strong&gt; to make your experience easy to digest.&lt;/p&gt;

&lt;p&gt;Short, impactful sentences are more effective than lengthy paragraphs. Hiring managers want to see the key information in a glance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Show Impact, Not Just Tasks
&lt;/h4&gt;

&lt;p&gt;It’s tempting to list everything you did at your previous job, but &lt;strong&gt;showing impact&lt;/strong&gt; is what truly makes your resume stand out.&lt;/p&gt;

&lt;p&gt;Don’t just state your responsibilities, &lt;strong&gt;highlight how your work benefited the company or project&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, instead of saying, “Developed an API,” you can say, “Developed a high-performance API that handled 1,000+ concurrent requests, improving response times by 30%.”&lt;/p&gt;

&lt;p&gt;Quantify your results whenever possible. Numbers and percentages can make your accomplishments more tangible and give hiring managers a clear sense of your contribution.&lt;/p&gt;

&lt;h4&gt;
  
  
  Proofread for Errors
&lt;/h4&gt;

&lt;p&gt;It might sound basic, but &lt;strong&gt;proofreading&lt;/strong&gt; your resume is a must. Even a small typo or grammatical mistake can make you seem careless and reduce your chances of getting an interview.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Use spell-check tools&lt;/strong&gt; and ask someone else to review your resume for any overlooked mistakes. A fresh set of eyes can catch errors you might have missed.&lt;/p&gt;

&lt;h4&gt;
  
  
  Use a Clean Layout
&lt;/h4&gt;

&lt;p&gt;First impressions matter! Your resume’s &lt;strong&gt;layout&lt;/strong&gt; should be neat, organized, and professional. Use a simple, easy-to-read font like &lt;strong&gt;Arial&lt;/strong&gt; or &lt;strong&gt;Calibri&lt;/strong&gt; and make sure the spacing is consistent.&lt;/p&gt;

&lt;p&gt;Margins should be even, and each section should be clearly defined with appropriate headings (e.g., “Work Experience,” “Education,” “Technical Skills”).&lt;/p&gt;

&lt;h3&gt;
  
  
  Include Links
&lt;/h3&gt;

&lt;p&gt;Sharing links to your work makes a big difference. It allows recruiters to easily view your portfolio, GitHub projects, or professional profiles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Link to your GitHub profile&lt;/strong&gt; with sample projects or code contributions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Link to your LinkedIn profile&lt;/strong&gt; for more details on your experience&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Personal website or portfolio&lt;/strong&gt; (if applicable) showcasing your work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Including these links shows that you’re tech-savvy and allows recruiters to dive deeper into your expertise.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Mistakes to Avoid
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Too Long:&lt;/strong&gt; Resumes should typically be 1–2 pages. If you’ve been in the industry for a while, try to keep your resume to a concise 2 pages. If you’re just starting, one page is often enough.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lies or Exaggerations:&lt;/strong&gt; Be honest about your skills and experience. Employers will eventually find out if you’ve overstated your abilities. Instead, focus on your strengths and show your eagerness to learn and grow.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Contact Info:&lt;/strong&gt; Never forget to include your contact info. Recruiters need to know how to reach you. Your phone number, email address, and LinkedIn or GitHub links should be clearly visible.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Overly Technical Language:&lt;/strong&gt; While you want to showcase your technical skills, keep in mind that not everyone reviewing your resume will be a technical expert. Try to write in a way that is understandable to both technical and non-technical people. If you’re using jargon, make sure it’s necessary and clear.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No Customization:&lt;/strong&gt; Don’t send the same resume for every job. Tailor your resume to the specific job description you’re applying for. Customizing your resume shows that you’ve put thought into your application and are genuinely interested in the role.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Ready to Craft Your Own Backend Developer Resume?
&lt;/h3&gt;

&lt;p&gt;To help you get started, we’ve made a free resume template that you can easily customize for your career.&lt;/p&gt;

&lt;p&gt;Simply &lt;a href="https://masteringbackend.com/resources/backend-developer-resume-template/backend-developer-resume-template" rel="noopener noreferrer"&gt;click the link to make your own copy&lt;/a&gt;, and start editing it to suit your experience and skills!&lt;/p&gt;

&lt;p&gt;This will give you a solid foundation to get noticed by hiring managers and recruiters. Best of luck, and happy job hunting!&lt;/p&gt;




&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://masteringbackend.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://masteringbackend.com/academy?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://backendweeky.dev?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will absolutely enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://getbackendjobs.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://masteringbackend.com/posts/backend-developer-resume-writing-the-ultimate-guide" rel="noopener noreferrer"&gt;&lt;em&gt;https://masteringbackend.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on May 25, 2025.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>backend</category>
      <category>resumewriting</category>
      <category>tutorial</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Backend Development: Ultimate Guide (2025)</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Sun, 18 May 2025 07:28:06 +0000</pubDate>
      <link>https://forem.com/masteringbackend/backend-development-ultimate-guide-2025-5aec</link>
      <guid>https://forem.com/masteringbackend/backend-development-ultimate-guide-2025-5aec</guid>
      <description>&lt;p&gt;Imagine you’re using a ride-hailing app like Uber. You request a ride, and within seconds, the app processes your location, finds the nearest driver, calculates the fare, and ensures the transaction is secure — all happening behind the scenes. This seamless experience is powered by &lt;a href="https://masteringbackend.com/hubs/backend-engineering" rel="noopener noreferrer"&gt;&lt;strong&gt;backend development&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Backend development is the backbone of web and mobile applications, handling everything from database management and business logic to security and API interactions.&lt;/p&gt;

&lt;p&gt;In this AI era, backend development is more crucial than ever as applications become increasingly data-driven, AI-integrated, and distributed.&lt;/p&gt;

&lt;p&gt;With the rise of real-time experiences, microservices, and scalable cloud infrastructure, a robust backend is the backbone of performance, security, and user trust in modern software.&lt;/p&gt;

&lt;p&gt;Suppose you’re a beginner looking to start a career in backend development or an experienced developer exploring the latest trends. In that case, this guide will take you through everything you need to know — from core concepts to advanced backend architectures.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Backend Development?
&lt;/h3&gt;

&lt;p&gt;Backend development, also known as &lt;strong&gt;server-side development&lt;/strong&gt; , is the practice of building and maintaining the infrastructure that powers applications.&lt;/p&gt;

&lt;p&gt;It manages &lt;strong&gt;data storage, security, authentication, business logic, and communication between frontend and backend services&lt;/strong&gt;. The backend is the brain of an application, ensuring that everything runs smoothly under the hood.&lt;/p&gt;

&lt;h3&gt;
  
  
  A Brief History of Backend Development
&lt;/h3&gt;

&lt;p&gt;In the early days of computing, applications were largely &lt;strong&gt;monolithic&lt;/strong&gt; , running on a single machine or server. As the internet evolved, &lt;strong&gt;client-server architectures&lt;/strong&gt; became standard, enabling applications to separate frontend and backend functionalities.&lt;/p&gt;

&lt;p&gt;Today, backend development has advanced to include &lt;strong&gt;microservices, serverless computing, and cloud-based architectures&lt;/strong&gt; that improve scalability and flexibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Responsibilities of Backend Developers:
&lt;/h3&gt;

&lt;p&gt;Backend developers play a crucial role in application development, handling tasks such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Managing Databases&lt;/strong&gt; : Storing, retrieving, and securing user data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Building APIs&lt;/strong&gt; : Connecting the frontend with the backend and third-party services.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handling Authentication &amp;amp; Authorization&lt;/strong&gt; : Implementing secure login and role-based access control.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimizing Performance&lt;/strong&gt; : Enhancing application speed and scalability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implementing Business Logic&lt;/strong&gt; : Enforcing application rules and workflows.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitoring and Debugging&lt;/strong&gt; : Ensuring application reliability and minimizing downtime.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  How Backend Development Works
&lt;/h3&gt;

&lt;p&gt;To understand how backend development works, let’s break it down with a &lt;strong&gt;real-world example — &lt;/strong&gt; a modern &lt;strong&gt;e-commerce website like Amazon&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-Step Breakdown of Backend Processes
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;User Request:&lt;/strong&gt; A customer searches for “wireless headphones.”: The request is sent from the frontend (React, Vue, or Angular) to the backend via an API call.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server Processing:&lt;/strong&gt; The request reaches the backend server (Node.js, Django, or Spring Boot), where it is processed. Middleware components handle security checks and request validations. Logging mechanisms store request details for monitoring.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Response to Frontend:&lt;/strong&gt; The backend sends a structured JSON response containing product details. The frontend displays the data dynamically, allowing user interaction.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;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%2Flll3bkrm7e2wqgpj92rx.png" class="article-body-image-wrapper"&gt;&lt;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%2Flll3bkrm7e2wqgpj92rx.png" alt="backend development" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This entire process happens within seconds, ensuring a seamless experience for users while maintaining security, performance, and scalability behind the scenes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend vs Backend Development
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Frontend Development:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Focus:&lt;/strong&gt; User Interface (UI) &amp;amp; User Experience (UX)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technologies:&lt;/strong&gt; HTML, CSS, JavaScript, React, Vue&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsibilities:&lt;/strong&gt; Creating visually appealing UI, client-side logic&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution:&lt;/strong&gt; Runs on the user’s browser&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Backend Development:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Focus:&lt;/strong&gt; Server-side logic, data handling&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Technologies:&lt;/strong&gt; Node.js, Django, Ruby on Rails, Spring Boot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Responsibilities:&lt;/strong&gt; Handling server requests, business logic, and database management&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Execution:&lt;/strong&gt; Runs on the server&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Core Technologies in Backend Development
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Programming Languages
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript (Node.js)&lt;/strong&gt;: Event-driven and asynchronous; ideal for scalable applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Python (Django/Flask)&lt;/strong&gt;: Simple syntax; strong for rapid development and AI integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java (Spring Boot)&lt;/strong&gt;: Enterprise-grade; widely used in large-scale applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go (Golang)&lt;/strong&gt;: Fast and efficient; suitable for microservices and performance-critical apps.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust&lt;/strong&gt; : Gaining popularity for system-level performance with safety guarantees.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Frameworks
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Express.js (Node.js):&lt;/strong&gt; Express.js is a framework of Node.js used to build scalable backend systems with Node.js. Here’s an &lt;a href="https://masteringbackend.com/posts/expressjs-5-tutorial-the-ultimate-guide/" rel="noopener noreferrer"&gt;ultimate guide to Express.js&lt;/a&gt; and learn how to build your first backend application with Node.js.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Django/Flask (Python):&lt;/strong&gt; Django and Flask are two different frameworks in the Python ecosystem, while both are used to build scalable backend systems, Django is more complete and popular than Flask. Here’s the &lt;a href="https://masteringbackend.com/posts/django-tutorial-the-ultimate-guide" rel="noopener noreferrer"&gt;ultimate guide to Django&lt;/a&gt; that will help you build your first Django backend application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Boot (Java):&lt;/strong&gt; Spring and Spring Boot are the most popular frameworks in the Java ecosystem used to build backend systems with Java. This &lt;a href="https://masteringbackend.com/posts/spring-boot" rel="noopener noreferrer"&gt;ultimate guide to Spring Boot&lt;/a&gt; will introduce you to building backend systems with Java.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NestJS (TypeScript):&lt;/strong&gt; Lastly, we have NestJS, which is another Node.js framework with support for TypeScript. Here’s the &lt;a href="https://masteringbackend.com/posts/nestjs-typescrpt-ultimate-guide" rel="noopener noreferrer"&gt;ultimate guide to learn NestJS&lt;/a&gt; and build your first NestJS backend application.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Databases
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Relational&lt;/strong&gt; : PostgreSQL, MySQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NoSQL&lt;/strong&gt; : MongoDB, Firebase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Caching&lt;/strong&gt; : Redis, Memcached&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  API Tools
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;REST and GraphQL&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Postman, Swagger, and Insomnia&lt;/strong&gt; for testing and documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Hosting &amp;amp; Cloud Services
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;AWS, Google Cloud, Microsoft Azure, Heroku, Vercel (for serverless functions)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend Development Best Practices
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Security
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Always hash passwords (bcrypt, Argon2)&lt;/li&gt;
&lt;li&gt;Use HTTPS with TLS&lt;/li&gt;
&lt;li&gt;Sanitize user input to prevent SQL injection and XSS&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Code Quality
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Modularize code using MVC or other design patterns&lt;/li&gt;
&lt;li&gt;Write reusable and testable functions&lt;/li&gt;
&lt;li&gt;Use linting tools and formatters (ESLint, Prettier)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Performance
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Use lazy loading and caching&lt;/li&gt;
&lt;li&gt;Optimize DB queries with indexes&lt;/li&gt;
&lt;li&gt;Monitor bottlenecks using APM tools (Datadog, New Relic)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Testing &amp;amp; CI/CD
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Write unit and integration tests (Jest, Mocha, PyTest)&lt;/li&gt;
&lt;li&gt;Automate deployments with GitHub Actions, Jenkins, or GitLab CI&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend Developer Roadmap for 2025
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Start with a language&lt;/strong&gt; : JavaScript, Python, or Java&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Learn the runtime/environment&lt;/strong&gt; : Node.js, JVM, Python&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pick a framework&lt;/strong&gt; : Express, Django, Spring Boot&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understand databases&lt;/strong&gt; : SQL (PostgreSQL), NoSQL (MongoDB)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build RESTful APIs&lt;/strong&gt; : Learn routing, controllers, middleware&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement authentication&lt;/strong&gt; : Sessions, JWT, OAuth&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explore cloud and deployments&lt;/strong&gt; : AWS, Docker, CI/CD&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Build real-world projects&lt;/strong&gt; : Blogs, eCommerce APIs, CRMs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Study system design &amp;amp; algorithms&lt;/strong&gt; : For job interviews and scale&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Join communities &amp;amp; contribute to open-source&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;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%2Fucqdkahrbtgoct7ouswe.png" class="article-body-image-wrapper"&gt;&lt;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%2Fucqdkahrbtgoct7ouswe.png" alt="backend development" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend Developer Salaries in 2025
&lt;/h3&gt;

&lt;p&gt;Backend development continues to be one of the most in-demand and well-compensated areas in tech. Salaries vary depending on factors such as location, experience, tech stack, and company size, according to &lt;a href="https://www.glassdoor.com/Salaries/index.htm" rel="noopener noreferrer"&gt;Glassdoor&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Global Salary Ranges:
&lt;/h4&gt;

&lt;p&gt;According to Glassdoor at the time of writing, below are the Salary ranges for Backend Developers in 2025:&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;United States&lt;/strong&gt; :
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Junior: $80,000–$110,000/year&lt;/li&gt;
&lt;li&gt;Mid-Level: $110,000–$140,000/year&lt;/li&gt;
&lt;li&gt;Senior: $140,000–$180,000+/year&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Europe (Germany, UK, Netherlands)&lt;/strong&gt;:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Junior: €45,000–€60,000/year&lt;/li&gt;
&lt;li&gt;Mid-Level: €60,000–€80,000/year&lt;/li&gt;
&lt;li&gt;Senior: €80,000–€110,000+/year&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;India&lt;/strong&gt; :
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Junior: ₹6–10 LPA&lt;/li&gt;
&lt;li&gt;Mid-Level: ₹10–20 LPA&lt;/li&gt;
&lt;li&gt;Senior: ₹20–40+ LPA&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Remote Roles&lt;/strong&gt; :
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Vary based on region, but often match global competitive rates if hired by international companies.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Top Paying Skills:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Microservices Architecture&lt;/li&gt;
&lt;li&gt;Cloud Infrastructure (AWS, GCP, Azure)&lt;/li&gt;
&lt;li&gt;DevOps &amp;amp; CI/CD&lt;/li&gt;
&lt;li&gt;System Design&lt;/li&gt;
&lt;li&gt;Rust/Go/Scala expertise&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Salary Tips:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Build an impressive portfolio with real-world projects&lt;/li&gt;
&lt;li&gt;Contribute to open-source and build your GitHub profile&lt;/li&gt;
&lt;li&gt;Learn cloud platforms and system design&lt;/li&gt;
&lt;li&gt;Don’t hesitate to negotiate or change companies for better compensation&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Trends in Backend Development (2025)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Serverless Functions&lt;/strong&gt; (AWS Lambda, Cloudflare Workers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge Computing&lt;/strong&gt; for low-latency processing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-augmented Backends&lt;/strong&gt; for personalization and analytics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rust and Go&lt;/strong&gt; adoption in high-performance systems&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure as Code&lt;/strong&gt; using Terraform, Pulumi&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Backend development is evolving faster than ever. Whether you’re building APIs, managing cloud services, or deploying microservices, the need for skilled backend engineers is growing.&lt;/p&gt;

&lt;p&gt;Mastering backend development means learning tools, understanding systems, writing secure and scalable code, and building real-world applications.&lt;/p&gt;

&lt;p&gt;Start small, build consistently, and follow the roadmap. The backend world in 2025 is yours to master.&lt;/p&gt;

&lt;h3&gt;
  
  
  FAQs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Q: Is backend development harder than frontend?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: Not necessarily — it depends on your interests. Backend focuses more on logic, data, and systems, while frontend is about UI/UX and design.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Can I become a backend developer without a CS degree?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: Absolutely. Many backend developers are self-taught. What matters most is your ability to build, test, and scale applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: How long does it take to become a backend developer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: With consistent learning and building projects, 6–12 months is a realistic range for job-ready skills.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Should I learn DevOps as a backend developer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A: Yes, at least the basics. Understanding CI/CD, Docker, and cloud infrastructure is essential for modern backend roles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Do I need to know frontend development to be a good backend developer?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; While it’s not mandatory, understanding frontend basics (like HTML, CSS, and JavaScript) helps in building better APIs and debugging issues related to data flow between the frontend and backend.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Is learning database management necessary for backend development?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Absolutely. Databases are central to backend development since they store and retrieve data for applications. Knowledge of SQL (PostgreSQL, MySQL) or NoSQL (MongoDB, Redis) is crucial.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Can I do backend development with JavaScript alone?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Yes, using &lt;strong&gt;Node.js&lt;/strong&gt; , you can build fully functional backend applications with JavaScript. It’s especially useful for real-time applications like chat apps and collaborative tools.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: What soft skills are important for backend developers?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Key soft skills include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Problem-solving:&lt;/strong&gt; Debugging issues efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Communication:&lt;/strong&gt; Explaining complex logic to non-technical stakeholders.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Collaboration:&lt;/strong&gt; Working well with frontend developers and DevOps engineers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptability:&lt;/strong&gt; Learning new technologies as they emerge.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Q: Should I learn NoSQL or SQL databases first?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; For beginners, learning &lt;strong&gt;SQL (e.g., MySQL, PostgreSQL)&lt;/strong&gt; is a good start because it’s structured and easier to understand. After mastering SQL, you can explore &lt;strong&gt;NoSQL (e.g., MongoDB, DynamoDB)&lt;/strong&gt; for more flexible, schema-less data storage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Q: Are backend developers in demand?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A:&lt;/strong&gt; Absolutely! With the rise of cloud computing, microservices, and API-driven applications, the demand for skilled backend developers is continuously growing.&lt;/p&gt;

&lt;h3&gt;
  
  
  Want to go deeper?
&lt;/h3&gt;

&lt;p&gt;Join our backend engineering community, access real-world backend projects, and check our &lt;a href="https://masteringbackend.com/hubs/backend-engineering" rel="noopener noreferrer"&gt;Backend Engineering Content Hub.&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com/academy?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://backendweeky.dev?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will absolutely enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getbackendjobs.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://masteringbackend.com/posts/backend-development-ultimate-guide" rel="noopener noreferrer"&gt;&lt;em&gt;https://masteringbackend.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on May 18, 2025.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>backend</category>
      <category>webdev</category>
      <category>tutorial</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to use the Default Trait in Rust</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Fri, 16 May 2025 21:12:34 +0000</pubDate>
      <link>https://forem.com/masteringbackend/how-to-use-the-default-trait-in-rust-5326</link>
      <guid>https://forem.com/masteringbackend/how-to-use-the-default-trait-in-rust-5326</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;When working with structs or enums in Rust, we often need a way to create a "standard" or "initial" instance without specifying all the fields every time. Manually setting each field can be repetitive, especially for complex types. How can we create a sensible default instance of a type conveniently?&lt;/p&gt;

&lt;p&gt;Enter the &lt;code&gt;std::default::Default&lt;/code&gt; trait. This trait provides a standardized way for types to offer a default value. If a type implements &lt;code&gt;Default&lt;/code&gt;, we can easily get a default instance, simplifying initialization and making our code cleaner, particularly when dealing with configuration structs or optional fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Need for Default Values
&lt;/h2&gt;

&lt;p&gt;Imagine a configuration struct for an application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct AppConfig {
    timeout_ms: u32,
    retries: u8,
    api_endpoint: String,
    enable_logging: bool,
}

fn main() {
    // Manually creating an instance feels verbose
    let config = AppConfig {
        timeout_ms: 5000,
        retries: 3,
        api_endpoint: "https://api.example.com".to_string(),
        enable_logging: false,
    };
    // ... use config ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we often need a configuration with standard settings (say, a timeout of 5000ms, 3 retries, a default endpoint, and logging disabled), writing this out repeatedly is tedious. Furthermore, if we add new fields to &lt;code&gt;AppConfig&lt;/code&gt;, we have to update every place where we manually create it.&lt;/p&gt;

&lt;p&gt;This is where the &lt;code&gt;Default&lt;/code&gt; trait shines.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing &lt;code&gt;std::default::Default&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;Default&lt;/code&gt; trait is remarkably simple. It's defined in the standard library &lt;code&gt;(std::default::Default)&lt;/code&gt; and requires implementing just one method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub trait Default: Sized {
    fn default() -&amp;gt; Self;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;default()&lt;/code&gt; associated function takes no arguments and returns an instance of the type &lt;code&gt;(Self)&lt;/code&gt; populated with default values. Many primitive types and standard library types already implement &lt;code&gt;Default&lt;/code&gt; (e.g., numbers default to 0, &lt;code&gt;bool&lt;/code&gt; to &lt;code&gt;false&lt;/code&gt;, &lt;code&gt;Option&lt;/code&gt; to &lt;code&gt;None&lt;/code&gt;, &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;Vec&lt;/code&gt; to empty ones).&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing &lt;code&gt;Default&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;There are two main ways to make our types implement &lt;code&gt;Default&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; Using &lt;code&gt;#[derive(Default)]&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If &lt;em&gt;all&lt;/em&gt; the fields within our struct also implement &lt;code&gt;Default&lt;/code&gt;, we can simply ask the compiler to generate the implementation for us using the &lt;code&gt;derive&lt;/code&gt; attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Default, Debug)] // We derive Default here!
struct AppConfig {
    timeout_ms: u32,       // u32 implements Default (defaults to 0)
    retries: u8,           // u8 implements Default (defaults to 0)
    api_endpoint: String,  // String implements Default (defaults to "")
    enable_logging: bool,  // bool implements Default (defaults to false)
}

fn main() {
    let default_config: AppConfig = AppConfig::default();
    println!("Default Config: {:?}", default_config);
    // Output: Default Config: AppConfig { timeout_ms: 0, retries: 0, api_endpoint: "", enable_logging: false }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the easiest way, but the derived defaults might not always be what we consider "sensible" (like 0 for &lt;code&gt;timeout_ms)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For enums, we can also derive &lt;code&gt;Default&lt;/code&gt;, but we must explicitly mark &lt;em&gt;one&lt;/em&gt; of the unit variants (a variant without data) with &lt;code&gt;#[default]&lt;/code&gt; to tell the compiler which one is the default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Default, Debug)]
enum LogLevel {
    Debug,
    Info,
    #[default] // Warning is the default level
    Warning,
    Error,
}

fn main() {
    let level: LogLevel = LogLevel::default();
    println!("Default log level: {:?}", level);
    // Output: Default log level: Warning
}

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

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Manual Implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If &lt;code&gt;derive&lt;/code&gt; isn't suitable (e.g., some fields don't implement &lt;code&gt;Default&lt;/code&gt;, or we need specific default values different from the derived ones), we can implement the trait manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Debug)] // Cannot derive Default if we implement manually
struct AppConfig {
    timeout_ms: u32,
    retries: u8,
    api_endpoint: String,
    enable_logging: bool,
}

// Manual implementation
impl Default for AppConfig {
    fn default() -&amp;gt; Self {
        AppConfig {
            timeout_ms: 5000, // Sensible default timeout
            retries: 3,       // Sensible default retries
            api_endpoint: "https://api.example.com".to_string(), // Default endpoint
            enable_logging: false, // Logging off by default
        }
    }
}

fn main() {
    let sensible_defaults: AppConfig = AppConfig::default();
    println!("Sensible Defaults: {:?}", sensible_defaults);
    // Output: Sensible Defaults: AppConfig { timeout_ms: 5000, retries: 3, api_endpoint: "https://api.example.com", enable_logging: false }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we provide the exact default values we want inside the &lt;code&gt;default()&lt;/code&gt; function. Remember, we cannot both &lt;code&gt;derive&lt;/code&gt; and manually implement &lt;code&gt;Default&lt;/code&gt; for the same type.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Default
&lt;/h2&gt;

&lt;p&gt;Once a type implements &lt;code&gt;Default&lt;/code&gt;, we can get its default value using &lt;code&gt;TypeName::default()&lt;/code&gt; or the fully qualified path &lt;code&gt;std::default::Default::default()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;A particularly useful pattern is combining &lt;code&gt;Default::default()&lt;/code&gt; with struct update syntax. This lets us specify only the fields we want to change, while the rest take their default values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Default, Debug)]
struct AppConfig {
    timeout_ms: u32,
    retries: u8,
    api_endpoint: String,
    enable_logging: bool,
}

impl AppConfig {
 fn default() -&amp;gt; Self { // Custom sensible defaults
        AppConfig {
            timeout_ms: 5000,
            retries: 3,
            api_endpoint: "https://api.example.com".to_string(),
            enable_logging: false,
        }
    }
}


fn main() {
    // Override only timeout and logging, keep other defaults
    let custom_config = AppConfig {
        timeout_ms: 10000,
        enable_logging: true,
        ..AppConfig::default() // Fill the rest with defaults
    };

    println!("Custom Config: {:?}", custom_config);
    // Output: Custom Config: AppConfig { timeout_ms: 10000, retries: 3, api_endpoint: "https://api.example.com", enable_logging: true }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes creating slightly modified instances very easy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Use Cases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Configuration Structs&lt;/strong&gt;: Providing sensible defaults for application settings.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Builder Pattern&lt;/strong&gt;: Often, the &lt;code&gt;Default&lt;/code&gt; implementation provides the starting point for a builder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initializing Collections&lt;/strong&gt;: Getting an empty &lt;code&gt;Vec&lt;/code&gt;, &lt;code&gt;HashMap&lt;/code&gt;, or &lt;code&gt;String&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Generic Code&lt;/strong&gt;: In generic functions, &lt;code&gt;T: Default&lt;/code&gt; allows creating a default instance of &lt;code&gt;T&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Testing&lt;/strong&gt;: Quickly creating instances with default data for tests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Considerations
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Derive Limitations&lt;/strong&gt;: &lt;code&gt;#[derive(Default)]&lt;/code&gt; only works if all fields implement &lt;code&gt;Default&lt;/code&gt;. If even one field doesn't, we must implement it manually.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Meaningful Defaults&lt;/strong&gt;: Ensure the default values make sense for the type's purpose. Sometimes the derived defaults (like 0 or empty strings) aren't appropriate.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Initialization Cost&lt;/strong&gt;: While usually cheap, the &lt;code&gt;default()&lt;/code&gt; function &lt;em&gt;can&lt;/em&gt; perform non-trivial work (like allocating memory for a &lt;code&gt;String&lt;/code&gt; or &lt;code&gt;Vec&lt;/code&gt;, or even more complex setup). Be aware if performance in initialization is critical.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The &lt;code&gt;std::default::Default&lt;/code&gt; trait provides a clean and standard way to create default instances of Rust types. Whether through the convenient &lt;code&gt;#[derive(Default)]&lt;/code&gt; attribute or a manual implementation for more control, it helps reduce boilerplate code and makes initializing structs and enums more ergonomic.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;Default::default()&lt;/code&gt; and struct update syntax, we can create instances with little fuss, focusing only on the values that differ from the standard defaults. If you want to learn more about rust you can always check out our &lt;a href="https://masteringbackend.com/courses/become-a-rust-backend-engineer" rel="noopener noreferrer"&gt;in-depth course on the language&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://masteringbackend.com?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://masteringbackend.com/academy?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://backendweeky.dev?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will absolutely enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://getbackendjobs.com?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>rust</category>
      <category>backend</category>
      <category>beginners</category>
      <category>tutorials</category>
    </item>
    <item>
      <title>How to Become a Backend Developer (2025)</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Fri, 16 May 2025 00:09:51 +0000</pubDate>
      <link>https://forem.com/masteringbackend/how-to-become-a-backend-developer-2025-53j8</link>
      <guid>https://forem.com/masteringbackend/how-to-become-a-backend-developer-2025-53j8</guid>
      <description>&lt;p&gt;The world of backend development can feel overwhelming at first, especially if you’re just starting. However, you’re in the right place if you’re a newbie or someone curious about backend development.&lt;/p&gt;

&lt;p&gt;In this guide, we will break down everything you need to know to become a backend developer this year, step by step.&lt;/p&gt;

&lt;p&gt;We will explore the core concepts of backend development, the technologies you’ll need to learn, and the pathways to becoming a proficient backend developer.&lt;/p&gt;

&lt;p&gt;By the end of this guide, you’ll have a clear roadmap for your journey.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Backend Development?
&lt;/h3&gt;

&lt;p&gt;Backend development refers to the server-side of web applications. It’s everything that happens behind the scenes that users don’t see, but is crucial to make the app work. As a backend developer, you will deal with databases, server management, APIs, and the business logic that powers the app.&lt;/p&gt;

&lt;p&gt;To help you visualize, let’s break down the core components of a backend application:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Server&lt;/strong&gt; : The physical or virtual machine that hosts the web application.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt; : The storage system where the application data is stored, such as MySQL, MongoDB, or PostgreSQL.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Application&lt;/strong&gt; : The code that runs the logic of the app. It handles the requests made by users and fetches the data from the database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;APIs (Application Programming Interfaces)&lt;/strong&gt;: These allow different systems to communicate with each other. Backend developers often create and manage APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s a &lt;a href="https://masteringbackend.com/hubs/backend-engineering?ref=devto" rel="noopener noreferrer"&gt;structured backend development content hub&lt;/a&gt; that will guide you step-by-step to become a great backend engineer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steps to Becoming a Backend Developer
&lt;/h3&gt;

&lt;p&gt;Below are the steps to become a backend developer. We have included course recommendations are the latter part of this guide to help you get started immediately.&lt;/p&gt;

&lt;p&gt;&lt;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%2F3blur0ys8di3rmuqv5yx.png" class="article-body-image-wrapper"&gt;&lt;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%2F3blur0ys8di3rmuqv5yx.png" width="800" height="1200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Learn the Fundamentals of Programming
&lt;/h3&gt;

&lt;p&gt;As with any programming role, learning the fundamentals of coding is crucial. Before jumping into backend-specific technologies, you should have a strong understanding of the following core concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Variables and Data Types&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Control Structures (if statements, loops)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Functions and Methods&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Object-Oriented Programming (OOP)&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Programming languages that are commonly used in backend development include Python, Java, JavaScript (Node.js), Ruby, PHP, and Go.&lt;/p&gt;

&lt;p&gt;If you’re just starting, we recommend &lt;strong&gt;Python&lt;/strong&gt; for its readability and versatility, which makes it a popular choice for beginners.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Choose a Backend Language
&lt;/h3&gt;

&lt;p&gt;Once you’re comfortable with the basics of programming, it’s time to pick a backend language. Each backend language has its strengths and is suited for different types of applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Recommended Backend Languages:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; : A great starting language due to its simplicity and wide usage in backend frameworks like Django and Flask.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript (Node.js)&lt;/strong&gt;: If you already know JavaScript from frontend development, learning Node.js will allow you to use the same language on both the frontend and backend.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java&lt;/strong&gt; : Known for its stability and scalability, Java is used for large enterprise-level applications and backend systems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruby&lt;/strong&gt; : Ruby on Rails is a popular framework for building web applications quickly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Go (Golang)&lt;/strong&gt;: A systems programming language designed by Google, Go is known for its speed and efficiency, making it ideal for high-performance applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For someone starting, we would recommend starting with &lt;strong&gt;Python&lt;/strong&gt; or &lt;strong&gt;JavaScript (Node.js)&lt;/strong&gt;, as both have extensive resources and beginner-friendly frameworks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;At Masteringbackend, we have a series of courses on&lt;/strong&gt; &lt;a href="https://masteringbackend.com/courses/become-a-python-backend-engineer?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Python&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;,&lt;/strong&gt; &lt;a href="https://masteringbackend.com/courses/become-a-nodejs-backend-engineer?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;,&lt;/strong&gt; &lt;a href="https://masteringbackend.com/courses/become-a-rust-backend-engineer?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Rust&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;,&lt;/strong&gt; &lt;a href="https://masteringbackend.com/courses/become-a-ruby-backend-engineer?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Ruby&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;, PHP, and&lt;/strong&gt; &lt;a href="https://masteringbackend.com/courses/become-a-golang-backend-engineer?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Golang&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;created following industry-standard roadmaps to turn you into a great backend engineer.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Learn about Databases
&lt;/h3&gt;

&lt;p&gt;Backend development involves dealing with data, so understanding how databases work is crucial. There are two primary types of databases you’ll encounter in backend development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Relational Databases (SQL)&lt;/strong&gt;: These databases store data in tables and use SQL (Structured Query Language) to interact with the data. Popular examples include &lt;strong&gt;MySQL&lt;/strong&gt; , &lt;strong&gt;PostgreSQL&lt;/strong&gt; , and  &lt;strong&gt;SQLite&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Non-relational Databases (NoSQL)&lt;/strong&gt;: These databases are more flexible and store data in formats like JSON or key-value pairs. Examples include &lt;strong&gt;MongoDB&lt;/strong&gt; , &lt;strong&gt;Redis&lt;/strong&gt; , and &lt;strong&gt;Cassandra&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learning SQL is essential for any backend developer, as it’s used to query relational databases. But understanding NoSQL databases is equally important, especially as the web becomes more data-driven.&lt;/p&gt;

&lt;h3&gt;
  
  
  When to Use SQL vs. NoSQL:
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;SQL (Relational)&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Best for structured data with well-defined schemas&lt;/li&gt;
&lt;li&gt;Excellent for complex relationships (e.g., joins)&lt;/li&gt;
&lt;li&gt;Example: MySQL, PostgreSQL, SQLite&lt;/li&gt;
&lt;li&gt;Use Cases: Financial systems, Inventory Management, ERP systems&lt;/li&gt;
&lt;li&gt;Vertically scalable (more powerful server)&lt;/li&gt;
&lt;li&gt;Strong ACID compliance (Atomicity, Consistency, Isolation, Durability)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;NoSQL (Non-relational)&lt;/strong&gt;
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Ideal for unstructured or rapidly changing data&lt;/li&gt;
&lt;li&gt;Less optimal for complex joins; better for hierarchical data with nested objects&lt;/li&gt;
&lt;li&gt;Examples: &lt;a href="https://masteringbackend.com/posts/mongodb-tutorial-the-ultimate-guide/?ref=devto" rel="noopener noreferrer"&gt;MongoDB&lt;/a&gt;, Cassandra, Redis&lt;/li&gt;
&lt;li&gt;Use Cases: Social media feeds, IoT data, Real-time analytics&lt;/li&gt;
&lt;li&gt;Horizontally scalable (multiple servers or clusters)&lt;/li&gt;
&lt;li&gt;Typically, eventual consistency, strong consistency can be achieved with extra setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://masteringbackend.com/hubs/backend-engineering/mastering-database?ref=devto" rel="noopener noreferrer"&gt;Get acquainted with databases&lt;/a&gt; and how they help store, retrieve, and manipulate data.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Understand How the Web Works
&lt;/h3&gt;

&lt;p&gt;As a backend developer, you’ll need to understand how the web works at a fundamental level. This includes learning about HTTP (Hypertext Transfer Protocol), the protocol that powers web communication. Here are a few key concepts to master:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTP Methods&lt;/strong&gt; : GET, POST, PUT, DELETE, and PATCH.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request and Response&lt;/strong&gt; : How clients (e.g., web browsers) send requests to the server, and how the server responds.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status Codes&lt;/strong&gt; : What different HTTP status codes (like 200, 404, 500) mean and how to handle them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RESTful APIs&lt;/strong&gt; : Learn how REST (Representational State Transfer) works to create standardized APIs that allow different systems to communicate.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding the flow of information from the client to the server is essential in backend development.&lt;/p&gt;

&lt;p&gt;Here’s a diagram that illustrates how various components interact in a backend system:&lt;/p&gt;

&lt;p&gt;&lt;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%2Fblm2kgrpzl9274h3egwh.png" class="article-body-image-wrapper"&gt;&lt;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%2Fblm2kgrpzl9274h3egwh.png" width="800" height="800"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Master a Backend Framework
&lt;/h3&gt;

&lt;p&gt;Once you’ve chosen your backend language and learned the basics, it’s time to dive into frameworks. Frameworks make backend development easier by providing tools and libraries that handle common tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Popular Backend Frameworks:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python&lt;/strong&gt; : &lt;a href="https://masteringbackend.com/hubs/backend-engineering/django-tutorial-the-ultimate-guide?ref=devto" rel="noopener noreferrer"&gt;Django&lt;/a&gt;, Flask&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JavaScript (&lt;/strong&gt;&lt;a href="https://masteringbackend.com/hubs/backend-engineering/nodejs-essentials?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Node.js&lt;/strong&gt;&lt;/a&gt;&lt;strong&gt;)&lt;/strong&gt;: &lt;a href="https://masteringbackend.com/hubs/backend-engineering/expressjs-5-tutorial-the-ultimate-guide?ref=devto" rel="noopener noreferrer"&gt;Express.js&lt;/a&gt;, Koa.js&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java&lt;/strong&gt; : &lt;a href="https://masteringbackend.com/hubs/backend-engineering/spring-boot?ref=devto" rel="noopener noreferrer"&gt;Spring Boot&lt;/a&gt;, Java EE&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ruby&lt;/strong&gt; : Ruby on Rails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these frameworks has its own strengths, but &lt;strong&gt;Django (Python)&lt;/strong&gt; and &lt;strong&gt;Express (Node.js)&lt;/strong&gt; are excellent choices for beginners. They both have large communities and extensive documentation, making it easier to get started.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Learn About APIs and Web Services
&lt;/h3&gt;

&lt;p&gt;As a backend developer, you’ll often need to create and manage &lt;strong&gt;APIs&lt;/strong&gt; (Application Programming Interfaces). APIs allow the backend to communicate with the frontend, third-party services, and external systems. Understanding how to build, test, and consume APIs is a crucial skill.&lt;/p&gt;

&lt;p&gt;A commonly used architectural style for APIs is &lt;strong&gt;REST (Representational State Transfer)&lt;/strong&gt;, but you may also encounter &lt;strong&gt;GraphQL&lt;/strong&gt; or  &lt;strong&gt;gRPC&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Building a RESTful API:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use appropriate &lt;strong&gt;HTTP methods&lt;/strong&gt; (GET, POST, PUT, DELETE)&lt;/li&gt;
&lt;li&gt;Ensure the API is &lt;strong&gt;stateless&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Design &lt;strong&gt;meaningful resource names&lt;/strong&gt; and use proper HTTP status codes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;API and API design is a broad topic and one that is necessary for every backend engineer. We have covered &lt;a href="https://newsletter.masteringbackend.com/archive?tags=API+Design" rel="noopener noreferrer"&gt;API and API design in our newsletter series here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  7. Version Control with Git
&lt;/h3&gt;

&lt;p&gt;Version control is an essential skill for any developer. &lt;strong&gt;Git&lt;/strong&gt; helps you track changes in your code, collaborate with other developers, and deploy your code to production.&lt;/p&gt;

&lt;p&gt;Learn how to use &lt;strong&gt;Git&lt;/strong&gt; for managing your code and collaborating with other developers on platforms like &lt;strong&gt;GitHub&lt;/strong&gt; or &lt;strong&gt;GitLab&lt;/strong&gt;. Mastering Git is a must-have skill for backend developers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Branching, Pull Requests, and Merge Conflicts&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Learn how to create feature branches and submit pull requests.&lt;/li&gt;
&lt;li&gt;Understand how to resolve &lt;strong&gt;merge conflicts&lt;/strong&gt; to maintain a clean codebase.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8. Testing and Debugging
&lt;/h3&gt;

&lt;p&gt;Testing is a vital part of backend development. It ensures that the application behaves as expected and helps catch bugs early in development. Learn how to write unit tests, integration tests, and use debugging tools to troubleshoot issues in your backend code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Types of Testing:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Unit Testing&lt;/strong&gt; : Testing individual components in isolation.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Integration Testing&lt;/strong&gt; : Testing how different components work together.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;End-to-End Testing&lt;/strong&gt; : Testing the entire flow of an application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Testing Tools&lt;/strong&gt; :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Jest&lt;/strong&gt; (for Node.js)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PyTest&lt;/strong&gt; (for Python)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JUnit&lt;/strong&gt; (for Java)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  9. Deploying Applications
&lt;/h3&gt;

&lt;p&gt;Once you’ve built a backend application, you need to deploy it. Learning how to deploy your backend code to a server is a critical step in the development process. Popular deployment platforms include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Heroku&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AWS (Amazon Web Services)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Google Cloud Platform&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Azure&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Learn how to deploy your backend applications to one of these platforms and understand the basics of &lt;strong&gt;CI/CD (Continuous Integration and Continuous Deployment)&lt;/strong&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  CI/CD and Docker
&lt;/h4&gt;

&lt;p&gt;Modern backend development requires not only deploying your applications but also setting up &lt;strong&gt;CI/CD&lt;/strong&gt; pipelines to automate testing and deployment. &lt;strong&gt;Docker&lt;/strong&gt; is a popular tool for containerizing applications, and &lt;strong&gt;Kubernetes&lt;/strong&gt; helps with managing these containers in a scalable way.&lt;/p&gt;

&lt;h3&gt;
  
  
  10. Build Projects
&lt;/h3&gt;

&lt;p&gt;The best way to cement your knowledge is by building projects. Here are some project ideas to get started:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build a simple &lt;strong&gt;CRUD&lt;/strong&gt; application (Create, Read, Update, Delete) using a backend framework and database.&lt;/li&gt;
&lt;li&gt;Create a &lt;strong&gt;blog API&lt;/strong&gt; that allows users to create and manage blog posts.&lt;/li&gt;
&lt;li&gt;Build an &lt;strong&gt;e-commerce API&lt;/strong&gt; for managing products, orders, and users.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can explore a list of &lt;a href="https://projects.masteringbackend.com" rel="noopener noreferrer"&gt;100+ backend projects&lt;/a&gt; you can start building now.&lt;/p&gt;

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

&lt;p&gt;Becoming a backend developer takes time, practice, and a commitment to learning. By following the steps outlined in this guide, starting with the basics, learning key technologies, and building projects, you’ll be well on your way to becoming a skilled backend developer.&lt;/p&gt;

&lt;p&gt;If you’re looking for structured courses that will guide you step-by-step, check out &lt;a href="https://MasteringBackend.com" rel="noopener noreferrer"&gt;&lt;strong&gt;MasteringBackend.com&lt;/strong&gt;&lt;/a&gt; for a variety of backend-focused courses designed to take you from beginner to pro.&lt;/p&gt;

&lt;p&gt;Remember, the journey to becoming a backend developer is all about consistency. Stay curious, keep building, and you’ll be creating powerful server-side applications in no time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com/academy?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://backendweeky.dev?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will absolutely enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getbackendjobs.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://masteringbackend.com/posts/how-to-become-a-backend-developer" rel="noopener noreferrer"&gt;&lt;em&gt;https://masteringbackend.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on May 16, 2025.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>backend</category>
      <category>webdev</category>
      <category>beginners</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Top 5 Python Frameworks</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Thu, 15 May 2025 23:43:03 +0000</pubDate>
      <link>https://forem.com/masteringbackend/top-5-python-frameworks-bb3</link>
      <guid>https://forem.com/masteringbackend/top-5-python-frameworks-bb3</guid>
      <description>&lt;h3&gt;
  
  
  Top 5 Python Frameworks (2025)
&lt;/h3&gt;

&lt;p&gt;Python is one of the most popular programming languages, especially in web development. With its simplicity and vast ecosystem, Python has become the go-to language for building scalable and efficient web applications.&lt;/p&gt;

&lt;p&gt;Whether you’re just starting your journey as a &lt;a href="https://masteringbackend.com/hubs/backend-engineering" rel="noopener noreferrer"&gt;backend developer&lt;/a&gt; or exploring frameworks to elevate your Python development skills, this article will dive into the &lt;strong&gt;top 5 Python frameworks&lt;/strong&gt; you should learn this year.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Choose Python for Web Development?
&lt;/h3&gt;

&lt;p&gt;Python has consistently ranked as one of the most beloved programming languages in the &lt;a href="https://survey.stackoverflow.co/2024/technology" rel="noopener noreferrer"&gt;Stack Overflow Developer Surveys&lt;/a&gt;. Its syntax is clean, easy to read, and highly versatile, making it an excellent choice for both beginners and seasoned developers.&lt;/p&gt;

&lt;p&gt;Here are some reasons why Python is ideal for web development:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Learning and Use:&lt;/strong&gt; Python’s simple and readable syntax makes it an ideal choice for beginners.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rich Libraries and Tools:&lt;/strong&gt; Python offers an extensive range of libraries that help developers with everything from machine learning to web scraping.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Strong Community Support:&lt;/strong&gt; Python has one of the largest developer communities, ensuring plenty of resources, tutorials, and frameworks are available.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability and Flexibility:&lt;/strong&gt; Python frameworks are capable of handling everything from small-scale applications to large, complex enterprise systems.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you’re ready to dive into Python for &lt;a href="https://masteringbackend.com/hubs/backend-engineering?ref=devto" rel="noopener noreferrer"&gt;Backend Development&lt;/a&gt;, I will recommend the &lt;a href="https://masteringbackend.com/courses/become-a-python-backend-engineer?ref=devto" rel="noopener noreferrer"&gt;“Become a Python Backend Engineer”&lt;/a&gt; course.&lt;/p&gt;

&lt;p&gt;It is an all-in-one Python course for learning backend engineering with Python. This comprehensive course is designed for Python developers seeking proficiency in Python.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fu1ys9ina1aduhfggg1tl.jpeg" class="article-body-image-wrapper"&gt;&lt;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%2Fu1ys9ina1aduhfggg1tl.jpeg" alt="Become a Python Backend Engineer" width="800" height="533"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Become a Python Backend Engineer&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Top 5 Python Frameworks to Learn in 2025
&lt;/h3&gt;

&lt;p&gt;We’ll explore the top 5 Python frameworks based on popularity, ease of use, community support, GitHub stars, and real-world usage. These frameworks will help you get up to speed quickly and are great for building production-ready applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Django
&lt;/h3&gt;

&lt;p&gt;Django is a high-level Python framework that promotes rapid development and clean, pragmatic design. It’s known for its “batteries-included” philosophy, meaning it provides all the necessary tools for developers to build a web application without needing third-party libraries.&lt;/p&gt;

&lt;h4&gt;
  
  
  Features:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Built-in admin interface for managing application data&lt;/li&gt;
&lt;li&gt;Secure by default (protection against SQL injection, cross-site scripting, etc.)&lt;/li&gt;
&lt;li&gt;Robust ORM (Object-Relational Mapping) for interacting with databases&lt;/li&gt;
&lt;li&gt;Supports RESTful APIs and easy integration with other APIs&lt;/li&gt;
&lt;li&gt;Extensible with third-party packages&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Popularity:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Stars: 83.5k+&lt;/li&gt;
&lt;li&gt;PyPI Downloads: 24.2M+ per month&lt;/li&gt;
&lt;li&gt;Usage: Widely used by companies like Instagram, Pinterest, and Spotify.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;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%2Fqqly20191yo2ql440bxl.png" class="article-body-image-wrapper"&gt;&lt;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%2Fqqly20191yo2ql440bxl.png" alt="PyPI Downloads" width="800" height="231"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Learning Resources:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://masteringbackend.com/posts/django-tutorial-the-ultimate-guide" rel="noopener noreferrer"&gt;Ultimate Django Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.djangoproject.com/" rel="noopener noreferrer"&gt;Official Django Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://djangoforbeginners.com/" rel="noopener noreferrer"&gt;Django for Beginners&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Flask
&lt;/h3&gt;

&lt;p&gt;Flask is a lightweight Python web framework that’s often described as a “micro-framework.” It doesn’t include many built-in features like Django, but is extremely flexible, allowing developers to pick and choose the libraries they need.&lt;/p&gt;

&lt;h4&gt;
  
  
  Features:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Minimalist approach with minimal setup&lt;/li&gt;
&lt;li&gt;Highly extensible (great for microservices and APIs)&lt;/li&gt;
&lt;li&gt;Built-in support for Jinja2 templating and Werkzeug WSGI toolkit&lt;/li&gt;
&lt;li&gt;Easy integration with other libraries for added functionality&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Popularity:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Stars: 69.5k+&lt;/li&gt;
&lt;li&gt;PyPI Downloads: 100.8M+ per month&lt;/li&gt;
&lt;li&gt;Usage: Flask powers applications like Netflix, Reddit, and Lyft.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;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%2F7o85gkvlbr56rsgxxlzz.png" class="article-body-image-wrapper"&gt;&lt;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%2F7o85gkvlbr56rsgxxlzz.png" alt="PyPI Downloads" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Learning Resources:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://flask.palletsprojects.com/en/stable/" rel="noopener noreferrer"&gt;Flask Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world" rel="noopener noreferrer"&gt;Flask Mega-Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  FastAPI
&lt;/h3&gt;

&lt;p&gt;FastAPI is a modern, fast (hence the name), and high-performance web framework for building APIs with Python. It is based on standard Python type hints, making it one of the most developer-friendly frameworks out there.&lt;/p&gt;

&lt;h4&gt;
  
  
  Features:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Extremely fast (competes with Go and Node.js in benchmarks)&lt;/li&gt;
&lt;li&gt;Automatic interactive API documentation (using Swagger UI and ReDoc)&lt;/li&gt;
&lt;li&gt;Built-in data validation using Python type hints&lt;/li&gt;
&lt;li&gt;Asynchronous programming support (great for building high-performance applications)&lt;/li&gt;
&lt;li&gt;Excellent for RESTful APIs and GraphQL&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Popularity:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Stars: 52k+&lt;/li&gt;
&lt;li&gt;PyPI Downloads: 92.9M+ per month&lt;/li&gt;
&lt;li&gt;Usage: Companies like Microsoft, Uber, and Netflix use FastAPI for building APIs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;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%2Fb0cqast082neuqkj77r0.png" class="article-body-image-wrapper"&gt;&lt;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%2Fb0cqast082neuqkj77r0.png" alt="PyPI Downloads" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Learning Resources:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://fastapi.tiangolo.com/" rel="noopener noreferrer"&gt;FastAPI Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.udemy.com/course/fastapi-the-complete-course/" rel="noopener noreferrer"&gt;FastAPI Course on Udemy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tornado
&lt;/h3&gt;

&lt;p&gt;Tornado is an asynchronous web framework and networking library designed to handle large numbers of simultaneous connections. It is ideal for building long-running network applications like real-time web services and websockets.&lt;/p&gt;

&lt;h4&gt;
  
  
  Features:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Non-blocking network I/O&lt;/li&gt;
&lt;li&gt;Real-time web functionality (perfect for chat applications, dashboards, etc.)&lt;/li&gt;
&lt;li&gt;Scalable for handling thousands of open connections&lt;/li&gt;
&lt;li&gt;Built-in support for websockets and HTTP/2&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Popularity:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Stars: 21.9k+&lt;/li&gt;
&lt;li&gt;PyPI Downloads: 55.9M+ per month&lt;/li&gt;
&lt;li&gt;Usage: Popular for real-time applications like FriendFeed and Dailymotion.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;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%2Fcr9zbgir6xuqp34wpsj5.png" class="article-body-image-wrapper"&gt;&lt;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%2Fcr9zbgir6xuqp34wpsj5.png" alt="PyPI Downloads" width="800" height="292"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Learning Resources:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.tornadoweb.org/en/stable/" rel="noopener noreferrer"&gt;Tornado Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/introduction-to-tornado/9781449312787/" rel="noopener noreferrer"&gt;Tornado in Action (Book)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pyramid
&lt;/h3&gt;

&lt;p&gt;Pyramid is a flexible and minimalistic Python framework used for building both small and large-scale applications. It allows developers to choose the right tools and libraries based on their project’s needs.&lt;/p&gt;

&lt;h4&gt;
  
  
  Features:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Highly flexible (developers can choose their templating, database, and other components)&lt;/li&gt;
&lt;li&gt;Easy-to-use authentication and authorization system&lt;/li&gt;
&lt;li&gt;Built-in support for URL dispatching and traversal&lt;/li&gt;
&lt;li&gt;Ideal for applications of any size (small or large)&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Popularity:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Stars: 4k+&lt;/li&gt;
&lt;li&gt;PyPI Downloads: 2.1M+ per month&lt;/li&gt;
&lt;li&gt;Usage: Pyramid is used by large companies like Mozilla.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;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%2F1ryyha5zfhx6jfc47z6v.png" class="article-body-image-wrapper"&gt;&lt;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%2F1ryyha5zfhx6jfc47z6v.png" alt="PyPI Downloads" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Learning Resources:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://trypyramid.com/" rel="noopener noreferrer"&gt;Pyramid Official Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://medium.com/@tushar_aggarwal/master-the-power-of-web-application-with-pyramid-a-step-by-step-guide-eacc55c38bb9" rel="noopener noreferrer"&gt;Pyramid Project Tutorial&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Choosing the Right Framework
&lt;/h3&gt;

&lt;p&gt;Selecting the right framework depends on your specific needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;For Rapid Development:&lt;/strong&gt; Django and Flask are excellent choices for quickly building applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For High-Performance APIs:&lt;/strong&gt; FastAPI and Tornado are great for building scalable, asynchronous APIs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;For Flexibility and Minimalism:&lt;/strong&gt; Pyramid and Flask provide a lot of flexibility with minimal overhead.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bonus
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.web2py.com/" rel="noopener noreferrer"&gt;&lt;strong&gt;Web2py&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; Great for beginners with its full-stack nature.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://docs.cherrypy.dev/" rel="noopener noreferrer"&gt;&lt;strong&gt;CherryPy&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;:&lt;/strong&gt; A minimalistic Python framework ideal for building small web applications.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Python offers a wide variety of web frameworks to choose from, each catering to different needs. Whether you are building a full-fledged web application or a high-performance API, there’s a Python framework suited to your project.&lt;/p&gt;

&lt;p&gt;By learning and mastering one or more of these frameworks, you’ll be able to develop scalable, efficient, and secure applications with Python in 2025.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Which framework are you excited to learn next? Let us know in the comments!&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com/academy?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://backendweeky.dev?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will absolutely enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getbackendjobs.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://masteringbackend.com/posts/top-5-python-frameworks" rel="noopener noreferrer"&gt;&lt;em&gt;https://masteringbackend.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on May 15, 2025.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>backend</category>
      <category>webdev</category>
      <category>begineers</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Top 5 Java Backend Development Courses (2025)</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Mon, 12 May 2025 19:14:36 +0000</pubDate>
      <link>https://forem.com/masteringbackend/top-5-java-backend-development-courses-bn6</link>
      <guid>https://forem.com/masteringbackend/top-5-java-backend-development-courses-bn6</guid>
      <description>&lt;p&gt;The internet is filled with lots of Java Backend Development Courses. Therefore, choosing the best Java backend development course can be a nightmare for newbies looking to start or change careers.&lt;/p&gt;

&lt;p&gt;Java is a popular programming language with a ground-breaking of millions of developers worldwide, with over &lt;a href="https://www.cisin.com/coffee-break/cost-of-outsourcing-your-software-project-to-a-company.html?ref=top-5-backend-development-courses&amp;amp;utm_source=masteringbackend&amp;amp;utm_campaign=top-5-backend-development-courses&amp;amp;utm_medium=blog" rel="noopener noreferrer"&gt;7.1 million professionals&lt;/a&gt; using it to build robust applications. Also, Java runs on over a billion devices according to Oracle.&lt;/p&gt;

&lt;p&gt;This groundbreaking record shows the value and relevancy of learning Java today as a backend engineer.&lt;/p&gt;

&lt;p&gt;You must choose the Best Java Course this year to achieve this goal effectively. A course that is designed to teach you the basics and also prepare you for the real challenges in your tech journey.&lt;/p&gt;

&lt;p&gt;If you’re planning to start your Java backend development journey, investing in the right Java Backend Development course could be the key to your success.&lt;/p&gt;

&lt;p&gt;To help reduce the time spent researching and searching for the best backend development course, we have already prepared a list of the &lt;strong&gt;top 5 best Java backend development courses&lt;/strong&gt;. These courses are thorough, beginner-friendly, and will prepare you for the job market.&lt;/p&gt;

&lt;p&gt;As part of our criteria, we have assembled the best course to learn Java for &lt;a href="https://masteringbackend.com/posts/how-to-become-a-backend-developer?ref=devto" rel="noopener noreferrer"&gt;Backend Development&lt;/a&gt;. These courses combine the right essential theories, including practical projects, while making learning enjoyable and effective.&lt;/p&gt;

&lt;p&gt;Additionally, these top-rated courses boast a 90% satisfaction rate from participants because they prepare them for the job and cover almost everything needed to become a Java Backend Developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Top 5 Java Backend Development Courses 2025
&lt;/h3&gt;

&lt;p&gt;Here’s a comprehensive guide to the Top 5 Best Java Backend Development Courses for 2025. These courses are called Roadmap Java Backend Courses, designed to take you from a complete beginner to a different level of expertise.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Become a Java+Spring Backend Developer.&lt;/li&gt;
&lt;li&gt;Mastering Java Backend with Oracle University.&lt;/li&gt;
&lt;li&gt;Learn Java by Creating Applications.&lt;/li&gt;
&lt;li&gt;Become a Java Backend Developer Bootcamp&lt;/li&gt;
&lt;li&gt;Building Scalable Java Microservices with Spring Boot and Spring Cloud&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Become a Java+Spring Backend Developer
&lt;/h3&gt;

&lt;p&gt;&lt;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%2Fua93uqsx21svx8i6kp8k.png" class="article-body-image-wrapper"&gt;&lt;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%2Fua93uqsx21svx8i6kp8k.png" alt="Become a Java+Spring Backend Developer" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The course takes you from ground zero and gradually moves you to become proficient in Java Backend Development.&lt;/p&gt;

&lt;p&gt;Below are the modules covered in this course:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Java Essentials:&lt;/strong&gt; The Java Essentials module is a complete, beginner-friendly course that explains the Core Java Basics, Object-Oriented Programming, Java syntax, and concepts such as variables, data types, arrays, strings, functions, control flow in Java, and error handling. This 49-video lesson course will expose you to core Java basics, Object-Oriented Programming, and Error Handling in Java.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Advanced Java:&lt;/strong&gt; As the name suggests, this is a complete advanced Java course that aims to teach you advanced concepts in Java, such as Collections, Java I/O Streams and Build Tool, and Multithreading in Java. This course explores I/O streams, collections, build tools, and multithreading in great detail, giving you the required knowledge to excel in Java Backend Development.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Design Patterns in Java:&lt;/strong&gt; In this module, you will learn the significance of design patterns and how to apply key Creational, Structural, and Behavioral patterns to create robust, maintainable, and scalable Java software solutions.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unit Testing in Java:&lt;/strong&gt; In this module, you will learn the importance of unit testing, the principles of Test-Driven Development (TDD), how to write test cases using JUnit, how to utilize advanced JUnit features like parameterized tests and test suites, and how to implement mocking with Mockito.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spring Framework and Spring Boot:&lt;/strong&gt; In this module, you’ll begin with the essentials of the Spring Framework, exploring how to configure beans using annotations and XML, manage bean lifecycles, and tap into Spring’s modular ecosystem, including AOP, Spring MVC, Spring Batch, Integration, and JMS. As you progress, you’ll dive deep into security, messaging, and cloud support through Spring Security and Spring Cloud.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Microservices in Java:&lt;/strong&gt; You will learn about the benefits and challenges of Microservices Architecture, how to build and configure microservices with Spring Boot, enable communication between microservices using Feign Client, implement event-driven messaging brokers, configure service discovery and registration with Eureka, and utilize API Gateway and load balancing with Zuul, Spring Cloud Gateway, and Ribbon.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Containerization:&lt;/strong&gt; In this module, you’ll learn to use Docker and Kubernetes by containerizing a Java application, working with Docker images, containers, registries, Dockerfiles, and Docker Compose, then dive into Kubernetes architecture and components like Pods, Nodes, and Clusters, set up clusters with Minikube and AWS, manage resources such as Deployments, Services, Ingress, ConfigMaps, and Secrets, scale applications, and implement monitoring and logging.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Milestone Projects in Java:&lt;/strong&gt; Build over 10+ projects while learning Java. Build a SaaS product in Java.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is an all-in-one Java and Spring course for learning backend engineering with Java. This comprehensive course is designed for Java developers seeking proficiency in Java.&lt;/p&gt;

&lt;h3&gt;
  
  
  Course Highlights:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Lifetime access to course materials&lt;/li&gt;
&lt;li&gt;Dedicated doubt resolution sessions&lt;/li&gt;
&lt;li&gt;Industry-oriented curriculum following the &lt;a href="http://Roadmap.sh?ref=top-5-backend-development-courses&amp;amp;utm_source=masteringbackend&amp;amp;utm_campaign=top-5-backend-development-courses&amp;amp;utm_medium=blog" rel="noopener noreferrer"&gt;Roadmap.sh&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Live sessions and webinars with industry experts&lt;/li&gt;
&lt;li&gt;Certification upon completion&lt;/li&gt;
&lt;li&gt;Real-world projects and case studies&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Course Duration:&lt;/strong&gt; 2–4 months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Course Price:&lt;/strong&gt; starting at $60 monthly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Course Link:&lt;/strong&gt; &lt;a href="https://masteringbackend.com/courses/become-a-java-spring-backend-engineer?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_campaign=top-5-backend-development-courses&amp;amp;utm_medium=blog" rel="noopener noreferrer"&gt;https://masteringbackend.com/courses/become-a-java-spring-backend-engineer&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Mastering Java Backend with Oracle University
&lt;/h3&gt;

&lt;p&gt;This is the official Java course from Oracle University. Java is currently owned by Oracle Corporation, which acquired Sun Microsystems, the original developers of Java.&lt;/p&gt;

&lt;p&gt;&lt;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%2F5jcpc420ynfku6up5xf6.png" class="article-body-image-wrapper"&gt;&lt;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%2F5jcpc420ynfku6up5xf6.png" alt="Mastering Java Backend with Oracle University" width="800" height="394"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, the Java core specification is managed through the Java Community Process (JCP), and Oracle owns the official Java Standard Edition (SE) implementation.&lt;/p&gt;

&lt;p&gt;The Oracle University has created a series of Java courses to help you develop in-demand programming skills with comprehensive training on the latest Java technology.&lt;/p&gt;

&lt;p&gt;Below are some of the Java Backend Development Courses from Oracle University:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Java Explorer:&lt;/strong&gt; Learn the basics of Java, such as variables, loops, objects, classes, arrays, and decision-making constructs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java SE 11: Programming Complete:&lt;/strong&gt; This course is intended for students with some programming experience and is a comprehensive training for Java developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Developing Applications for the Java EE 7 Platform:&lt;/strong&gt; This course teaches you how to build and deploy enterprise applications with Java EE.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architect Enterprise Application with Java EE:&lt;/strong&gt; This course teaches you how to develop robust architectures for enterprise Java applications.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Oracle University is a subscription-based platform; you can access most of the courses when you subscribe. Also, you can access certification courses from the university and earn a recognized certificate from Oracle.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Learn Java by Creating Applications
&lt;/h3&gt;

&lt;p&gt;This is an official course from JetBrains, the creators of JetBrains IDEs and the Kotlin programming language. It teaches Java development practically by building chatbots, games, algorithms, and even neural networks from scratch.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fy1cxmxb2bzaffisl0xus.png" class="article-body-image-wrapper"&gt;&lt;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%2Fy1cxmxb2bzaffisl0xus.png" alt="Learn Java by Creating Applications" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The course is subdivided into tracks to help you gradually expand your knowledge and improve in the areas that interest you.&lt;/p&gt;

&lt;p&gt;Below is a list of the tracks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Java for Beginners:&lt;/strong&gt; This course is for complete Java beginners and programming newbies. Its track will help you start and prepare for some computer science certifications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java Core:&lt;/strong&gt; This track is a great choice for learners who want to gain a firm grasp of Java fundamentals and be introduced to algorithmic problems and mathematical models.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java Backend Developer:&lt;/strong&gt; This track was specifically designed to prepare you for your first Junior Developer interview. It contains tasks necessary to successfully pass your technical interview.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Java Desktop Application Developer:&lt;/strong&gt; If you already know the basics of Java and would like to create desktop apps, this is the right track for you. You will also master the Swing framework.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Course Highlights:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;200+ interactive projects&lt;/li&gt;
&lt;li&gt;Personalized study plan&lt;/li&gt;
&lt;li&gt;Integration with JetBrains IDEs&lt;/li&gt;
&lt;li&gt;Knowledge map&lt;/li&gt;
&lt;li&gt;Instant feedback&lt;/li&gt;
&lt;li&gt;Certificate of completion&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  4. Become a Java Backend Developer Bootcamp
&lt;/h3&gt;

&lt;p&gt;All-in-one Java Bootcamp for learning backend engineering with Java. This bootcamp is designed for Java developers seeking proficiency in Java.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fdq3g8y64qbhksfr5ik4d.png" class="article-body-image-wrapper"&gt;&lt;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%2Fdq3g8y64qbhksfr5ik4d.png" alt="Become a Java Backend Developer Bootcamp" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Java Backend Developer Bootcamp is a comprehensive backend engineering bootcamp that will equip you with the skills to take your backend engineering career to the next level.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bootcamp Outline:
&lt;/h3&gt;

&lt;p&gt;Below is the content outline that we cover in this bootcamp to turn you into a great backend developer using the Java programming language.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basics of Back-End Development&lt;/li&gt;
&lt;li&gt;Server-side Programming Language (Java)&lt;/li&gt;
&lt;li&gt;Build a Back-End with Spring&lt;/li&gt;
&lt;li&gt;API and API Design&lt;/li&gt;
&lt;li&gt;Git and GitHub&lt;/li&gt;
&lt;li&gt;Mastering Database&lt;/li&gt;
&lt;li&gt;Deployment&lt;/li&gt;
&lt;li&gt;Software Testing&lt;/li&gt;
&lt;li&gt;Software Design Principles&lt;/li&gt;
&lt;li&gt;Web Security&lt;/li&gt;
&lt;li&gt;Caching and CDNs&lt;/li&gt;
&lt;li&gt;Message Brokers and Search Engines&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Containerization and CI/CD&lt;/li&gt;
&lt;li&gt;Data Structures and Algorithms&lt;/li&gt;
&lt;li&gt;What to Expect in a Technical Interview (Landing Job)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Bootcamp Highlights:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;200+ recorded videos and lessons&lt;/li&gt;
&lt;li&gt;Personalized study plan&lt;/li&gt;
&lt;li&gt;3-month access to the instructor&lt;/li&gt;
&lt;li&gt;Lifetime Access and updates&lt;/li&gt;
&lt;li&gt;Practice Projects&lt;/li&gt;
&lt;li&gt;Career Services&lt;/li&gt;
&lt;li&gt;Instant feedback&lt;/li&gt;
&lt;li&gt;Certificate of completion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Course Duration:&lt;/strong&gt; 2–4 months.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Course Link:&lt;/strong&gt; &lt;a href="https://academy.masteringbackend.com?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_campaign=top-5-backend-development-courses&amp;amp;utm_medium=blog" rel="noopener noreferrer"&gt;https://academy.masteringbackend.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Course Price:&lt;/strong&gt; starting at $500 monthly.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Building Scalable Java Microservices with Spring Boot and Spring Cloud
&lt;/h3&gt;

&lt;p&gt;Are you a Java developer looking to take your microservices skills to the next level?&lt;/p&gt;

&lt;p&gt;Google Cloud, in collaboration with Coursera, offers an &lt;strong&gt;intermediate-level course&lt;/strong&gt; that teaches you how to build scalable, cloud-native microservices using &lt;strong&gt;Spring Boot&lt;/strong&gt; and &lt;strong&gt;Spring Cloud&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this course, you’ll learn how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build Spring Boot microservices that integrate with &lt;strong&gt;Google Cloud managed services&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;strong&gt;Pub/Sub&lt;/strong&gt; and &lt;strong&gt;Spring Integration&lt;/strong&gt; for message handling&lt;/li&gt;
&lt;li&gt;Store data with &lt;strong&gt;Cloud SQL&lt;/strong&gt; and migrate to &lt;strong&gt;Cloud Spanner&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Implement distributed tracing using &lt;strong&gt;Cloud Trace&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This course is perfect if you already have some experience with Java and want to deepen your skills by working with real-world cloud tools.&lt;/p&gt;

&lt;h3&gt;
  
  
  Course Highlights:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;3 hands-on modules&lt;/li&gt;
&lt;li&gt;Approx. &lt;strong&gt;12 hours of content&lt;/strong&gt;  — learn at your own pace&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2 assignments&lt;/strong&gt; to test your knowledge&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;shareable certificate&lt;/strong&gt; for your LinkedIn or resume&lt;/li&gt;
&lt;li&gt;Lifetime access via &lt;strong&gt;Coursera Plus&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The course is taught by instructors from &lt;strong&gt;Google Cloud&lt;/strong&gt;, who bring real-world expertise and practical examples to every lesson.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Choosing the right Java backend development course in 2025 is more than just selecting a popular program — it’s about finding the one that aligns with your learning style, career goals, and current experience level.&lt;/p&gt;

&lt;p&gt;Whether you’re a complete beginner starting from scratch or a developer looking to deepen your expertise, the courses listed above provide a comprehensive roadmap to mastering Java for backend engineering.&lt;/p&gt;

&lt;p&gt;From industry-aligned programs like &lt;strong&gt;“&lt;/strong&gt; &lt;a href="https://masteringbackend.com/courses/become-a-java-spring-backend-engineer?ref=devto&amp;amp;utm_source=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Become a Java + Spring Backend Developer&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;”&lt;/strong&gt; by Masteringbackend to practical, hands-on courses from &lt;strong&gt;Oracle University&lt;/strong&gt; , &lt;strong&gt;JetBrains&lt;/strong&gt; , and &lt;strong&gt;Google Cloud&lt;/strong&gt; , these options are carefully curated to help you build real-world skills and become job-ready.&lt;/p&gt;

&lt;p&gt;Each course combines structured modules, project-based learning, expert-led instruction, and certifications that can give you an edge in today’s competitive job market.&lt;/p&gt;

&lt;p&gt;Now is the best time to invest in your backend engineering career. Choose the course that suits you best and take the first step toward becoming a professional Java Backend Developer in 2025.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ready to Become a Java Backend Engineer?
&lt;/h3&gt;

&lt;p&gt;If you’re serious about launching your backend engineering career with Java, then &lt;a href="https://masteringbackend.com/courses/become-a-java-spring-backend-engineer?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_campaign=top-5-backend-development-courses&amp;amp;utm_medium=blog" rel="noopener noreferrer"&gt;&lt;strong&gt;Become a Java+Spring Backend Developer&lt;/strong&gt;&lt;/a&gt; is the ultimate course to get you there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Join thousands of developers already learning Java the right way.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With a structured roadmap, real-world projects, and modules that take you from complete beginner to job-ready backend engineer, this course is your all-in-one solution.&lt;/p&gt;

&lt;p&gt;You’ll learn everything from Java fundamentals to advanced Spring Boot microservices and even containerization with Docker and Kubernetes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lifetime access&lt;/li&gt;
&lt;li&gt;Hands-on projects&lt;/li&gt;
&lt;li&gt;Live sessions with experts&lt;/li&gt;
&lt;li&gt;Certification on completion&lt;/li&gt;
&lt;li&gt;Designed by backend engineers for backend engineers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://masteringbackend.com/courses/become-a-java-spring-backend-engineer?ref=devto&amp;amp;utm_source=devto&amp;amp;utm_campaign=top-5-backend-development-courses&amp;amp;utm_medium=blog" rel="noopener noreferrer"&gt;Start Learning Today&lt;/a&gt; — and build your future in backend engineering!&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com?ref=devto&amp;amp;utm_source=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com/academy?ref=devto&amp;amp;utm_source=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://backendweeky.dev?ref=devto&amp;amp;utm_source=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will absolutely enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getbackendjobs.com?ref=devto&amp;amp;utm_source=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://masteringbackend.com/posts/top-5-java-backend-development-courses" rel="noopener noreferrer"&gt;&lt;em&gt;https://masteringbackend.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on May 12, 2025.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>backend</category>
      <category>java</category>
      <category>webdev</category>
      <category>beginners</category>
    </item>
    <item>
      <title>How to Use the Default Trait in Rust</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Fri, 09 May 2025 20:25:08 +0000</pubDate>
      <link>https://forem.com/kaperskyguru/how-to-use-the-default-trait-in-rust-1h0d</link>
      <guid>https://forem.com/kaperskyguru/how-to-use-the-default-trait-in-rust-1h0d</guid>
      <description>&lt;p&gt;&lt;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%2Fs07irvpprtqfyuinbt1y.png" class="article-body-image-wrapper"&gt;&lt;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%2Fs07irvpprtqfyuinbt1y.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Introduction
&lt;/h3&gt;

&lt;p&gt;When working with structs or enums in Rust, we often need a way to create a “standard” or “initial” instance without specifying all the fields every time. Manually setting each field can be repetitive, especially for complex types. How can we create a sensible default instance of a type conveniently?&lt;/p&gt;

&lt;p&gt;Enter the std::default::Default trait. This trait provides a standardized way for types to offer a default value. If a type implements Default, we can easily get a default instance, simplifying initialization and making our code cleaner, particularly when dealing with configuration structs or optional fields.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Need for Default Values
&lt;/h3&gt;

&lt;p&gt;Imagine a configuration struct for an application:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;pre&amp;gt;&amp;lt;code class="lnguage-rust"&amp;gt; struct AppConfig struct AppConfig {
    timeout_ms: u32,
    retries: u8,
    api_endpoint: String,
    enable_logging: bool,
}

fn main() {
    // Manually creating an instance feels verbose
    let config = AppConfig {
        timeout_ms: 5000,
        retries: 3,
        api_endpoint: "https://api.example.com".to_string(),
        enable_logging: false,
    };
    // ... use config ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we often need a configuration with standard settings (say, a timeout of 5000ms, 3 retries, a default endpoint, and logging disabled), writing this out repeatedly is tedious. Furthermore, if we add new fields to AppConfig, we have to update every place where we manually create it.&lt;/p&gt;

&lt;p&gt;This is where the Default trait shines.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introducing std::default::Default
&lt;/h3&gt;

&lt;p&gt;The Default trait is remarkably simple. It's defined in the standard library (std::default::Default) and requires implementing just one method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pub trait Default: Sized {
    fn default() -&amp;gt; Self;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default() associated function takes no arguments and returns an instance of the type (Self) populated with default values. Many primitive types and standard library types already implement Default (e.g., numbers default to 0, bool to false, Option to None, String and Vec to empty ones).&lt;/p&gt;

&lt;h3&gt;
  
  
  Implementing Default
&lt;/h3&gt;

&lt;p&gt;There are two main ways to make our types implement Default:&lt;/p&gt;

&lt;p&gt;If &lt;em&gt;all&lt;/em&gt; the fields within our struct also implement Default, we can simply ask the compiler to generate the implementation for us using the derive attribute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Default, Debug)] // We derive Default here!
struct AppConfig {
    timeout_ms: u32, // u32 implements Default (defaults to 0)
    retries: u8, // u8 implements Default (defaults to 0)
    api_endpoint: String, // String implements Default (defaults to "")
    enable_logging: bool, // bool implements Default (defaults to false)
}

fn main() {
    let default_config: AppConfig = AppConfig::default();
    println!("Default Config: {:?}", default_config);
    // Output: Default Config: AppConfig { timeout_ms: 0, retries: 0, api_endpoint: "", enable_logging: false }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the easiest way, but the derived defaults might not always be what we consider “sensible” (like 0 for timeout_ms).&lt;/p&gt;

&lt;p&gt;For enums, we can also derive Default, but we must explicitly mark &lt;em&gt;one&lt;/em&gt; of the unit variants (a variant without data) with #[default] to tell the compiler which one is the default:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Default, Debug)]
enum LogLevel {
    Debug,
    Info,
    #[default] // Warning is the default level
    Warning,
    Error,
}

fn main() {
    let level: LogLevel = LogLevel::default();
    println!("Default log level: {:?}", level);
    // Output: Default log level: Warning
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Manual Implementation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If derive isn't suitable (e.g., some fields don't implement Default, or we need specific default values different from the derived ones), we can implement the trait manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;struct AppConfig {
    timeout_ms: u32,
    retries: u8,
    api_endpoint: String,
    enable_logging: bool,
}

// Manual implementation
impl Default for AppConfig {
    fn default() -&amp;gt; Self {
        AppConfig {
            timeout_ms: 5000, // Sensible default timeout
            retries: 3, // Sensible default retries
            api_endpoint: "https://api.example.com".to_string(), // Default endpoint
            enable_logging: false, // Logging off by default
        }
    }
}

fn main() {
    let sensible_defaults: AppConfig = AppConfig::default();
    println!("Sensible Defaults: {:?}", sensible_defaults);
    // Output: Sensible Defaults: AppConfig { timeout_ms: 5000, retries: 3, api_endpoint: "https://api.example.com", enable_logging: false }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we provide the exact default values we want inside the default() function. Remember, we cannot both derive and manually implement Default for the same type.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Default
&lt;/h3&gt;

&lt;p&gt;Once a type implements Default, we can get its default value using TypeName::default() or the fully qualified path std::default::Default::default().&lt;/p&gt;

&lt;p&gt;A particularly useful pattern is combining Default::default() with struct update syntax. This lets us specify only the fields we want to change, while the rest take their default values:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Default, Debug)]
struct AppConfig {
    timeout_ms: u32,
    retries: u8,
    api_endpoint: String,
    enable_logging: bool,
}

impl AppConfig {
 fn default() -&amp;gt; Self { // Custom sensible defaults
        AppConfig {
            timeout_ms: 5000,
            retries: 3,
            api_endpoint: "https://api.example.com".to_string(),
            enable_logging: false,
        }
    }
}

fn main() {
    // Override only timeout and logging, keep other defaults
    let custom_config = AppConfig {
        timeout_ms: 10000,
        enable_logging: true,
        ..AppConfig::default() // Fill the rest with defaults
    };

    println!("Custom Config: {:?}", custom_config);
    // Output: Custom Config: AppConfig { timeout_ms: 10000, retries: 3, api_endpoint: "https://api.example.com", enable_logging: true }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes creating slightly modified instances very easy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Use Cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Configuration Structs&lt;/strong&gt; : Providing sensible defaults for application settings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Builder Pattern&lt;/strong&gt; : Often, the Default implementation provides the starting point for a builder.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initializing Collections&lt;/strong&gt; : Getting an empty Vec, HashMap, or String.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generic Code&lt;/strong&gt; : In generic functions, T: Default allows creating a default instance of T.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt; : Quickly creating instances with default data for tests.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Considerations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Derive Limitations&lt;/strong&gt; : #[derive(Default)] only works if all fields implement Default. If even one field doesn't, we must implement it manually.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meaningful Defaults&lt;/strong&gt; : Ensure the default values make sense for the type’s purpose. Sometimes the derived defaults (like 0 or empty strings) aren’t appropriate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Initialization Cost&lt;/strong&gt; : While usually cheap, the default() function &lt;em&gt;can&lt;/em&gt; perform non-trivial work (like allocating memory for a String or Vec, or even more complex setup). Be aware if performance in initialization is critical.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;The std::default::Default trait provides a clean and standard way to create default instances of Rust types. Whether through the convenient #[derive(Default)] attribute or a manual implementation for more control, it helps reduce boilerplate code and makes initializing structs and enums more ergonomic.&lt;/p&gt;

&lt;p&gt;With Default::default() and struct update syntax, we can create instances with little fuss, focusing only on the values that differ from the standard defaults. If you want to learn more about Rust, you can always check out our &lt;a href="https://masteringbackend.com/courses/become-a-rust-backend-engineer?ref=devto" rel="noopener noreferrer"&gt;in-depth course on the language&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com/academy?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://backendweeky.dev?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getbackendjobs.com?ref=devto" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://masteringbackend.com/posts/how-to-use-the-default-trait-in-rust" rel="noopener noreferrer"&gt;&lt;em&gt;https://masteringbackend.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on May 9, 2025.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>rustprogramminglangu</category>
      <category>backenddevelopment</category>
      <category>rust</category>
    </item>
    <item>
      <title>Spring Boot + Docker: Dockerizing Java Spring Boot Apps</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Tue, 06 May 2025 20:50:05 +0000</pubDate>
      <link>https://forem.com/masteringbackend/spring-boot-docker-dockerizing-java-spring-boot-apps-ob4</link>
      <guid>https://forem.com/masteringbackend/spring-boot-docker-dockerizing-java-spring-boot-apps-ob4</guid>
      <description>&lt;p&gt;&lt;strong&gt;Docker has changed the way we build, run, and scale applications.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It lets you package your app with everything it needs, so it runs the same everywhere, on your computer, on someone else’s, or a server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker is one of the most popular tools for this.&lt;/strong&gt; It helps keep things consistent and avoids the “it works on my machine” problem.&lt;/p&gt;

&lt;p&gt;In this blog, we will see how to containerize a Spring Boot application using Docker, step by step. By the end, you’ll be able to run your Spring Boot app inside a Docker container and deploy it seamlessly.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Docker?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; gets its name from the term “dock worker,” someone who loads and unloads shipping containers. Similarly, Docker “loads” and “runs” software containers.&lt;/li&gt;
&lt;li&gt;Using Docker, we can implement the containerization technologies.&lt;/li&gt;
&lt;li&gt;Containerization is a concept that allows us to package software applications along with the necessary libraries and binaries required to run them. This package is called an image.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Docker is a tool/platform that makes it easy to create, manage, or run containers.&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://masteringbackend.com/posts/docker-tutorial" rel="noopener noreferrer"&gt;Click here to read the definitive guide to Docker.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;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%2Fpdh40brhxksklhp6ahaf.png" class="article-body-image-wrapper"&gt;&lt;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%2Fpdh40brhxksklhp6ahaf.png" alt="Spring boot application" width="800" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Docker?
&lt;/h3&gt;

&lt;p&gt;Suppose we’re building a Spring Boot application on our local machine. It runs perfectly because our system has the correct versions of Java, Maven, and other necessary tools installed. However, when we want to deploy this application to another machine, we have to manually set up all the required software.&lt;/p&gt;

&lt;p&gt;In real-world projects, applications are typically deployed to multiple environments for testing and production, such as &lt;strong&gt;DEV&lt;/strong&gt; , &lt;strong&gt;UAT&lt;/strong&gt; , &lt;strong&gt;SIT&lt;/strong&gt; , and  &lt;strong&gt;PROD&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Ensuring that each of these environments has the exact setup can be a time-consuming and error-prone process. One machine might have a different Java version or might be missing certain dependencies, leading to unexpected errors.&lt;/p&gt;

&lt;p&gt;Now, if we use Docker, we can create a &lt;strong&gt;Dockerfile&lt;/strong&gt; that includes our application, the exact Java version, and all required settings.&lt;/p&gt;

&lt;p&gt;Once packaged into a &lt;strong&gt;Docker image&lt;/strong&gt; , the application can run on &lt;strong&gt;any system with Docker installed,&lt;/strong&gt; without worrying about environment-specific configurations. We can run the same container across all environments just as we do locally.&lt;/p&gt;

&lt;p&gt;This consistency not only saves time but also greatly simplifies both &lt;strong&gt;development&lt;/strong&gt; and &lt;strong&gt;deployment&lt;/strong&gt;.&lt;/p&gt;

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

&lt;p&gt;To follow along, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://masteringbackend.com/hubs/java-backend-development" rel="noopener noreferrer"&gt;Basic knowledge of Java, Spring Boot, and Maven&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Installed:&lt;/li&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;Maven&lt;/li&gt;
&lt;li&gt;Docker &amp;amp; Docker CLI&lt;/li&gt;
&lt;li&gt;An IDE (e.g., IntelliJ, VS Code)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Simple Spring Boot Application
&lt;/h3&gt;

&lt;p&gt;We’ll use a simple Spring Boot project with just one REST API that returns &lt;strong&gt;“Hello, World!”&lt;/strong&gt; when the &lt;strong&gt;/hello&lt;/strong&gt; endpoint is accessed. We’ve pushed the code to GitHub, so you can simply clone the repository and switch to the master branch.&lt;/p&gt;

&lt;p&gt;You can check out the full code here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/ayushstwt/docker-spring-boot" rel="noopener noreferrer"&gt;https://github.com/ayushstwt/docker-spring-boot&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Spring Boot Application on localhost
&lt;/h3&gt;

&lt;p&gt;&lt;a href="http://localhost:8080/hello" rel="noopener noreferrer"&gt;http://localhost:8080/hello&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;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%2Fppwyedf9zlsofjf9hfsc.png" class="article-body-image-wrapper"&gt;&lt;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%2Fppwyedf9zlsofjf9hfsc.png" alt="test" width="800" height="439"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker Terminology
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Docker file-&lt;/strong&gt; It contains a set of instructions to build a Docker image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker Image&lt;/strong&gt; - It is a package that contains application code + dependencies.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker Hub&lt;/strong&gt; - It is a registry to store Docker images. (AWS ECR)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker Container&lt;/strong&gt; - It is a runtime instance of our application. Run-time instance of an image. If you run Docker image container will be created, that’s where our application is running.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;To generate a Docker image from our Spring Boot application, there are three different commonly used approaches. We can choose one of the themes.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dockerfile&lt;/li&gt;
&lt;li&gt;Buildpacks&lt;/li&gt;
&lt;li&gt;Google Jib&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Approach 1
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Running a Spring Boot application as a container using a Dockerfile
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;  — Run the maven command, “ &lt;strong&gt;mvn clean install&lt;/strong&gt; “. to generate a fat jar inside the target folder.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt; - Create the file name &lt;strong&gt;Dockerfile&lt;/strong&gt; inside the root directory to generate a Docker image.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;FROM openjdk:17-jdk-slim
COPY target/docker-spring-boot-0.0.1-SNAPSHOT.jar docker-spring-boot-0.0.1-SNAPSHOT.jar
ENTRYPOINT ["java","-jar","/docker-spring-boot-0.0.1-SNAPSHOT.jar"]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here in the above file&lt;/p&gt;

&lt;p&gt;FROM openjdk:17-jdk-slim - Uses a lightweight OpenJDK 17 base image to run the Spring Boot application. COPY target/docker-spring-boot-0.0.1-SNAPSHOT.jar docker-spring-boot-0.0.1-SNAPSHOT.jar - Copies the built JAR file from the target directory into the Docker image. ENTRYPOINT ["java","-jar","/docker-spring-boot-0.0.1-SNAPSHOT.jar"] - Defines the command to run the Spring Boot JAR when the container starts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To use Docker, first download Docker Desktop from &lt;a href="http://docker.com/products/docker-desktop" rel="noopener noreferrer"&gt;docker.com/products/docker-desktop&lt;/a&gt;. Pick the version for your OS (Windows or macOS). If you’re on Linux, follow the guide at &lt;a href="http://docs.docker.com/engine/install" rel="noopener noreferrer"&gt;docs.docker.com/engine/install&lt;/a&gt;. Install it like any app and launch Docker Desktop.&lt;/li&gt;
&lt;li&gt;Next, open your terminal and run docker login. Enter your Docker Hub username and password. If you don't have an account, create one at &lt;a href="http://hub.docker.com/signup" rel="noopener noreferrer"&gt;hub.docker.com/signup&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Once logged in, you’re ready to build images, run containers, and manage apps easily.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Execute the Docker command to generate the Docker image based on the tag name. Make sure that your Docker Desktop is running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// syntax
docker build -t your-image-name:tag .

// command
docker build -t ayshriv/docker-spring-boot:latest .
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After executing this command, you’ll see an output indicating that the Docker image was successfully generated. The docker build command is used to create a Docker image from a Dockerfile. The -t flag allows you to specify a name for your image and optionally assign a version tag.&lt;/p&gt;

&lt;p&gt;For example, in docker-spring-boot:latest, docker-spring-boot is the image name, and latest is the tag. The . (dot) at the end tells Docker to use the current directory as the build context, where it looks for the Dockerfile and all necessary files.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fwxhs90w9gxmtkr7mpjmy.png" class="article-body-image-wrapper"&gt;&lt;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%2Fwxhs90w9gxmtkr7mpjmy.png" alt="code sample" width="800" height="192"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To verify that the image was successfully created, use the docker images command. This will list all the Docker images available on your system.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fkgkujz19yt6sjwoz030d.png" class="article-body-image-wrapper"&gt;&lt;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%2Fkgkujz19yt6sjwoz030d.png" alt="code sample" width="614" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;  — Next, execute the following command to create and run a Docker container based on the image you just built.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -p 8080:8080 ayshriv/docker-spring-boot:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command docker run -p 8080:8080 ayshriv/docker-spring-boot:latest is used to start a Docker container from the image we built. The -p 8080:8080 option maps port &lt;strong&gt;8080 on your host machine&lt;/strong&gt; to port &lt;strong&gt;8080 inside the container&lt;/strong&gt; , allowing you to access the application via &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here, ayshriv/docker-spring-boot:latest is the name and tag of the Docker image. This command runs your Spring Boot application inside a container, exactly as it would run in production.&lt;/p&gt;

&lt;p&gt;In the 8080:8080 format:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;first value (host port)&lt;/strong&gt; is the external port on your machine.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;second value (container port)&lt;/strong&gt; is the internal port your app listens on inside the container.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After executing this command, you should see output indicating that the container is running successfully.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fwdjf239keh587c4aesa4.png" class="article-body-image-wrapper"&gt;&lt;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%2Fwdjf239keh587c4aesa4.png" alt="code sample" width="800" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To check if your container is running, use the docker ps command. This will display a list of all currently running containers.&lt;/p&gt;

&lt;p&gt;The Docker image name ayshriv/docker-spring-boot:latest, ayshriv is your Docker Hub username, which helps identify you as the owner of the image. docker-spring-boot is the name of your application, and it's good practice to keep this name short, clear, and related to what your app does.&lt;/p&gt;

&lt;p&gt;The part after the colon, latest, is the tag, which usually refers to the current or most recent version of the image. You can also use tags like v1.0, prod, or dev to manage different versions.&lt;/p&gt;

&lt;p&gt;While creating a Docker image using a Dockerfile is effective and widely adopted, it does have some drawbacks. One major issue is the &lt;strong&gt;size of the resulting image&lt;/strong&gt; , which can be quite large, especially when using base images like OpenJDK. Larger images take more time to build, transfer, and start, which can negatively impact development speed and deployment efficiency.&lt;/p&gt;

&lt;p&gt;Additionally, &lt;strong&gt;maintaining a Dockerfile requires ongoing effort&lt;/strong&gt; , as you’ll need to update it whenever your application’s structure or dependencies change. In our case, the generated image size is around &lt;strong&gt;428MB&lt;/strong&gt; , which is quite substantial.&lt;/p&gt;

&lt;p&gt;The next approach we’ll explore helps reduce image size and requires minimal manual effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach 2
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Running a Spring Boot application as a container using Buildpacks
&lt;/h4&gt;

&lt;p&gt;Cloud Native Buildpacks transform your application source code into images that can run on any cloud. It is an alternative approach to Dockerfiles.&lt;/p&gt;

&lt;p&gt;With the help of Buildpacks, we can automatically generate production-ready images from our application source code without writing a Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://buildpacks.io/" rel="noopener noreferrer"&gt;https://buildpacks.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1-&lt;/strong&gt; We need to add the given configuration inside the pom.xml for the image name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;configuration&amp;gt;
                    &amp;lt;image&amp;gt;
                            &amp;lt;name&amp;gt;ayshriv/${project.artifactId}:latest&amp;lt;/name&amp;gt;
                    &amp;lt;/image&amp;gt;
                &amp;lt;/configuration&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
  &amp;lt;/build&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, we also follow the same naming convention for image names.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2-&lt;/strong&gt; Now, we run the given Maven command to generate the Docker image without the need for a Dockerfile (make sure that Docker Desktop is running).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvn spring-boot:build-image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;  — Next, execute the following command to create a Docker container from the image, along with the required port mapping.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -p 8080:8080 ayshriv/docker-spring-boot:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With this approach, there’s &lt;strong&gt;no need to create a Dockerfile manually&lt;/strong&gt; , and the resulting image size is also reduced. However, one limitation is that &lt;strong&gt;Docker Desktop still needs to be installed&lt;/strong&gt; on your local machine to build and run the image.&lt;/p&gt;

&lt;p&gt;To overcome this dependency, we can use &lt;strong&gt;Google JIB&lt;/strong&gt; , a tool specifically designed for Java applications. JIB allows you to generate a Docker image for your Spring Boot application &lt;strong&gt;without needing a Dockerfile or Docker installed locally&lt;/strong&gt; , while also producing smaller and more optimized images.&lt;/p&gt;

&lt;h3&gt;
  
  
  Approach 3
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Running a Spring Boot application as a container using Google JIB
&lt;/h4&gt;

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

&lt;p&gt;Google JIB is used to build container images for your Java applications, without the need for a Dockerfile and Docker Desktop.&lt;/p&gt;

&lt;p&gt;It is an alternative approach to Dockerfiles. With the help of Google JIB, we can automatically generate production-ready images from our application source code without writing a Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; We need to add the given configuration inside the pom.xml for the image name.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;build&amp;gt;
  &amp;lt;plugins&amp;gt;
    &amp;lt;plugin&amp;gt;
      &amp;lt;groupId&amp;gt;com.google.cloud.tools&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;jib-maven-plugin&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;3.4.0&amp;lt;/version&amp;gt; 
      &amp;lt;configuration&amp;gt;
        &amp;lt;to&amp;gt;
          &amp;lt;image&amp;gt;ayshriv/${project.artifactId}:latest&amp;lt;/image&amp;gt;
        &amp;lt;/to&amp;gt;
      &amp;lt;/configuration&amp;gt;
    &amp;lt;/plugin&amp;gt;
  &amp;lt;/plugins&amp;gt;
&amp;lt;/build&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Run the given Maven command to generate the Docker image (for Google JIB, there is no need for Docker Desktop to be installed on your local system).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mvn compile jib:dockerBuild
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; After this, execute the following command to create and run a Docker container based on the image, with the appropriate port mapping.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docker run -p 8080:8080 ayshriv/docker-spring-boot:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this approach, we eliminate the need for a Dockerfile, and the resulting image size is significantly reduced.&lt;/p&gt;

&lt;p&gt;However, one limitation is that Docker Desktop must be installed on the local system to build and run Docker images. To overcome this dependency, we can use &lt;strong&gt;Google JIB,&lt;/strong&gt; a powerful tool specifically designed for Java applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Google JIB&lt;/strong&gt; allows us to containerize our Spring Boot application &lt;strong&gt;without writing a Dockerfile&lt;/strong&gt; or having Docker installed locally.&lt;/p&gt;

&lt;p&gt;It integrates directly with Maven or Gradle, enabling seamless image creation and pushing to container registries. Additionally, JIB optimizes image layering, which helps in &lt;strong&gt;reducing image size&lt;/strong&gt; and speeding up rebuild times during development.&lt;/p&gt;

&lt;p&gt;Some Commonly Used Docker Commands for Java Developers&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# 1. Build Docker image from Dockerfile (usually for Spring Boot app)
docker build -t my-java-app .

# 2. List all images
docker images

# 3. Run the Docker container from the built image
docker run -d -p 8080:8080 --name java-app-container my-java-app

# 4. View running containers
docker ps

# 5. View all containers (including stopped ones)
docker ps -a

# 6. Stop a running container
docker stop java-app-container

# 7. Start a stopped container
docker start java-app-container

# 8. Restart a container
docker restart java-app-container

# 9. Remove a container
docker rm java-app-container

# 10. Remove an image
docker rmi my-java-app

# 11. View logs of a container (helpful for debugging)
docker logs java-app-container

# 12. Execute a command inside a running container (like inspecting files, checking logs)
docker exec -it java-app-container bash

# 13. Tag an image (e.g., for pushing to Docker Hub)
docker tag my-java-app ayushshrivastaav/my-java-app:latest

# 14. Login to Docker Hub
docker login

# 15. Push image to Docker Hub
docker push ayushshrivastaav/my-java-app:latest

# 16. Pull image from Docker Hub
docker pull ayushshrivastaav/my-java-app:latest

# 17. Remove all stopped containers
docker container prune -f

# 18. Remove all unused images
docker image prune -a -f

# 19. Check Docker version
docker version

# 20. View system-wide Docker resource usage
docker system df

# 21. Compose up (if using docker-compose.yml for multi-container apps)
docker-compose up -d

# 22. Compose down
docker-compose down
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com/academy?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://backendweeky.dev?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will absolutely enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getbackendjobs.com?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://masteringbackend.com/posts/spring-boot-docker-dockerizing-java-spring-boot-apps" rel="noopener noreferrer"&gt;&lt;em&gt;https://masteringbackend.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on May 6, 2025.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>tutorial</category>
      <category>beginners</category>
      <category>webdev</category>
      <category>backend</category>
    </item>
    <item>
      <title>Next.js vs Astro vs Remix: Choosing the Right Front-end Framework</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Mon, 05 May 2025 12:10:06 +0000</pubDate>
      <link>https://forem.com/strapi/nextjs-vs-astro-vs-remix-choosing-the-right-front-end-framework-2n1k</link>
      <guid>https://forem.com/strapi/nextjs-vs-astro-vs-remix-choosing-the-right-front-end-framework-2n1k</guid>
      <description>&lt;p&gt;Discover the differences between Next.js, Astro, and Remix to find the right one for your next Strapi project.&lt;/p&gt;

&lt;p&gt;&lt;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%2F3qj9w3vajezfnafeoiwk.png" class="article-body-image-wrapper"&gt;&lt;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%2F3qj9w3vajezfnafeoiwk.png" width="800" height="472"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Next.js vs Astro vs Remix: Choosing the Right Front-end Framework&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When selecting a framework for your web application, it is critical to consider the developer experience that it provides. Astro, Remix, and Next.js all build on top of React to provide a more streamlined experience. They have a low learning curve, so if you’re already familiar with React, you can quickly pick them up and get started.&lt;/p&gt;

&lt;p&gt;We evaluate each to help you decide which framework is appropriate for you, not to determine which is faster or better.&lt;/p&gt;
&lt;h3&gt;
  
  
  What is Astro?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://astro.build/" rel="noopener noreferrer"&gt;Astro&lt;/a&gt; is a modern web framework built on React and a static site builder that requires little or no JavaScript to deliver lightning-fast, high-performance websites with a modern developer experience. It allows you to create websites using UI components from your favorite &lt;a href="https://strapi.io/blog/comprehensive-review-of-top-javascript-frontend-frameworks" rel="noopener noreferrer"&gt;JavaScript UI frameworks&lt;/a&gt; such as React, Svelte, Vue, and others.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Example of an Astro component
---
// Component imports and JavaScript execution
import { Image } from 'astro:assets';
import ReusableButton from '../components/Button.astro';

// Data fetching in the component
const response = await fetch('https://api.example.com/data');
const data = await response.json();
---

&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;My Astro Site&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Welcome to Astro!&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;This is a static site with minimal JavaScript&amp;lt;/p&amp;gt;

    &amp;lt;!-- Using imported components --&amp;gt;
    &amp;lt;ReusableButton text="Click me" /&amp;gt;

    &amp;lt;!-- Displaying fetched data --&amp;gt;
    &amp;lt;ul&amp;gt;
      {data.items.map(item =&amp;gt; (
        &amp;lt;li&amp;gt;{item.name}&amp;lt;/li&amp;gt;
      ))}
    &amp;lt;/ul&amp;gt;

    &amp;lt;!-- Only this component will ship with JavaScript --&amp;gt;
    &amp;lt;InteractiveCounter client:load initialCount={5} /&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Astro websites are primarily static, with no JavaScript code by default. When a component (for example, image carousels, dark and light mode) requires JavaScript code to run, Astro only loads that component and any necessary dependencies. The rest of the site remains static lightweight HTML. Check out Astro’s &lt;a href="https://docs.astro.build/en/getting-started/" rel="noopener noreferrer"&gt;Getting Started tutorial&lt;/a&gt; for an excellent introduction.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Astro is more flexible: you can build UI with any popular component library (React, Preact, Vue, Svelte, Solid, and others) or Astro’s HTML-like component syntax, similar to HTML + JSX.&lt;/li&gt;
&lt;li&gt;Astro can build statically via SSG or deploy to SSR environments via adapters like Deno, Vercel serverless, Netlify serverless, and Node.js, with more to come.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: astro.config.mjs - Configuring SSR with an adapter

import { defineConfig } from 'astro/config';
import vercel from '@astrojs/vercel/serverless';
import react from '@astrojs/react';
import vue from '@astrojs/vue';

// https://astro.build/config
export default defineConfig({
  // Enable SSR for dynamic rendering
  output: 'server',
  // Deploy to Vercel serverless functions
  adapter: vercel(),
  // Add support for multiple UI frameworks
  integrations: [react(), vue()]
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;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%2F2fl12d1befajxg4fwwkc.png" class="article-body-image-wrapper"&gt;&lt;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%2F2fl12d1befajxg4fwwkc.png" width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Next.js?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; is an open-source React framework for quickly creating server-rendered React applications. It adds structure and features and handles the React tooling and configuration required for your application.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: pages/index.js - Next.js page component

import Head from 'next/head';
import Link from 'next/link';
import { useState } from 'react';

export default function Home({ featuredPosts }) {
  const [count, setCount] = useState(0);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Head&amp;gt;
        &amp;lt;title&amp;gt;My Next.js Website&amp;lt;/title&amp;gt;
      &amp;lt;/Head&amp;gt;

      &amp;lt;main&amp;gt;
        &amp;lt;h1&amp;gt;Welcome to my website&amp;lt;/h1&amp;gt;
        &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;
          Count: {count}
        &amp;lt;/button&amp;gt;

        &amp;lt;h2&amp;gt;Featured Posts&amp;lt;/h2&amp;gt;
        &amp;lt;ul&amp;gt;
          {featuredPosts.map(post =&amp;gt; (
            &amp;lt;li key={post.id}&amp;gt;
              &amp;lt;Link href={`/posts/${post.slug}`}&amp;gt;
                {post.title}
              &amp;lt;/Link&amp;gt;
            &amp;lt;/li&amp;gt;
          ))}
        &amp;lt;/ul&amp;gt;
      &amp;lt;/main&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// Data fetching at build time
export async function getStaticProps() {
  const res = await fetch('https://api.example.com/featured-posts');
  const featuredPosts = await res.json();

  return {
    props: { featuredPosts },
    // Re-generate page at most once per hour
    revalidate: 3600
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can be used to solve common application requirements like routing, data retrieval, and integrations. Next.js was created to provide an easy-to-use development framework that would reduce the time and effort required to develop full-fledged, SSR-friendly web applications while improving the end user and developer experience. The &lt;a href="https://nextjs.org/docs" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; is a great place to start if you want to begin with this framework.&lt;/p&gt;

&lt;p&gt;Next.js fully embraces React Server Components (RSCs), enabling server-side data fetching directly within components. This reduces client-side JavaScript and improves performance. Also, &lt;a href="https://nextjs.org/docs/app/api-reference/turbopack" rel="noopener noreferrer"&gt;Turbopack&lt;/a&gt; is now stable, offering lightning-fast bundling and significantly reducing build times for large projects.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/dashboard/page.js - React Server Component in Next.js

// Server Component (no "use client" directive)
import { getUser } from '@/lib/auth';
import { getDashboardData } from '@/lib/data';
import DashboardMetrics from '@/components/DashboardMetrics';
import ClientSideInteractions from '@/components/ClientSideInteractions';

export default async function DashboardPage() {
  // This code runs only on the server
  const user = await getUser();
  const { metrics, recentActivity } = await getDashboardData(user.id);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Welcome back, {user.name}&amp;lt;/h1&amp;gt;

      {/* Server component with no client JS */}
      &amp;lt;DashboardMetrics data={metrics} /&amp;gt;

      {/* This component will be hydrated on the client */}
      &amp;lt;ClientSideInteractions initialData={recentActivity} /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;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%2F919uavbovdhk9yfjuwp8.png" class="article-body-image-wrapper"&gt;&lt;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%2F919uavbovdhk9yfjuwp8.png" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Remix?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://remix.run/" rel="noopener noreferrer"&gt;Remix&lt;/a&gt; is an edge-native, full-stack JavaScript framework for building modern, fast, and resilient user experiences. It unifies the client and server with web standards so you can think less about code and more about your product. Remix is now React Router 7, and it continues to evolve with the latest web development trends.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/routes/posts.$slug.jsx - A Remix route component

import { json } from '@remix-run/node';
import { useLoaderData, Form, useActionData } from '@remix-run/react';
import { getPost, addComment } from '~/models/post.server';

// Server-side data loading
export async function loader({ params }) {
  const post = await getPost(params.slug);

  if (!post) {
    throw new Response("Not Found", { status: 404 });
  }

  return json({ post });
}

// Server-side form handling
export async function action({ request, params }) {
  const formData = await request.formData();
  const comment = formData.get('comment');

  if (!comment || comment.length &amp;lt; 3) {
    return json({ error: "Comment must be at least 3 characters" });
  }

  await addComment({ postSlug: params.slug, text: comment });
  return json({ success: true });
}

// Client component using server data
export default function Post() {
  const { post } = useLoaderData();
  const actionData = useActionData();

  return (
    &amp;lt;article&amp;gt;
      &amp;lt;h1&amp;gt;{post.title}&amp;lt;/h1&amp;gt;
      &amp;lt;div dangerouslySetInnerHTML={{ __html: post.content }} /&amp;gt;

      &amp;lt;h2&amp;gt;Leave a comment&amp;lt;/h2&amp;gt;
      &amp;lt;Form method="post"&amp;gt;
        &amp;lt;textarea name="comment" required minLength={3} /&amp;gt;
        {actionData?.error &amp;amp;&amp;amp; &amp;lt;p className="error"&amp;gt;{actionData.error}&amp;lt;/p&amp;gt;}
        &amp;lt;button type="submit"&amp;gt;Submit&amp;lt;/button&amp;gt;
      &amp;lt;/Form&amp;gt;

      &amp;lt;h2&amp;gt;Comments&amp;lt;/h2&amp;gt;
      &amp;lt;ul&amp;gt;
        {post.comments.map(comment =&amp;gt; (
          &amp;lt;li key={comment.id}&amp;gt;{comment.text}&amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/article&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remix now supports Static Site Generation (SSG), allowing developers to pre-render pages at build time. This feature bridges the gap between Remix and frameworks like Next.js. Currently, Remix’s loaders and actions have been optimized for parallel data fetching, reducing load times for complex applications.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Example of Static Site Generation in Remix (React Router 7)

// Path: routes/blog.static.$slug.tsx

import { json } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
import { getPost, getAllPostSlugs } from '~/models/post.server';

// Generate static paths at build time
export async function generateStaticParams() {
  const slugs = await getAllPostSlugs();
  return slugs.map(slug =&amp;gt; ({ slug }));
}

// Load data at build time
export async function loader({ params }) {
  const post = await getPost(params.slug);
  if (!post) {
    throw new Response("Not Found", { status: 404 });
  }
  return json({ post });
}

export default function BlogPost() {
  const { post } = useLoaderData();
  return (
    &amp;lt;article&amp;gt;
      &amp;lt;h1&amp;gt;{post.title}&amp;lt;/h1&amp;gt;
      &amp;lt;div dangerouslySetInnerHTML={{ __html: post.content }} /&amp;gt;
    &amp;lt;/article&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;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%2Ff8jlpggeijffd8p75brn.png" class="article-body-image-wrapper"&gt;&lt;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%2Ff8jlpggeijffd8p75brn.png" width="800" height="438"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;p&gt;Let’s look at the key features of Astro, Remix, and Next.js to understand what makes each framework unique and how they cater to different development needs.&lt;/p&gt;

&lt;h4&gt;
  
  
  Astro
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Zero-config: Any config explained will be handled by our astro add CLI command (i.e., add Svelte support with astro add svelte).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Example of using the Astro CLI to add integrations
npm create astro@latest my-project
cd my-project
# Add Tailwind CSS support
npx astro add tailwind
# Add React support
npx astro add react
# Add image optimization
npx astro add image
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Astro is UI-agnostic: meaning you can Bring Your Own UI Framework (BYOF).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
// Path: src/pages/mixed-frameworks.astro

// Using multiple frameworks in the same page
import ReactCounter from '../components/ReactCounter.jsx';
import VueToggle from '../components/VueToggle.vue';
import SvelteCard from '../components/SvelteCard.svelte';
---

&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Multi-Framework Page&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Using Multiple Frameworks&amp;lt;/h1&amp;gt;

    &amp;lt;!-- React component --&amp;gt;
    &amp;lt;ReactCounter client:visible initialCount={0} /&amp;gt;

    &amp;lt;!-- Vue component --&amp;gt;
    &amp;lt;VueToggle client:idle /&amp;gt;

    &amp;lt;!-- Svelte component --&amp;gt;
    &amp;lt;SvelteCard client:only="svelte" title="Svelte Card" /&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Easy to use: Astro’s goal is to be accessible to every web developer. Astro was designed to feel familiar and approachable regardless of skill level or experience with web development.&lt;/li&gt;
&lt;li&gt;Fast by default: An Astro website can load 40% faster with 90% less JavaScript than the site built with the most popular React web framework.&lt;/li&gt;
&lt;li&gt;Server-first: Astro leverages server-side rendering over client-side rendering as much as possible.&lt;/li&gt;
&lt;li&gt;Content-based: Astro’s unique focus on content lets Astro make tradeoffs and deliver unmatched performance features that wouldn’t make sense for more application-focused web frameworks to implement.&lt;/li&gt;
&lt;li&gt;Fully-featured but flexible: Astro is an all-in-one web framework with everything you need to build a website. Astro includes a component syntax, file-based routing, asset handling, a build process, bundling, optimizations, data fetching, and more. You can build great websites without ever reaching outside of Astro’s core feature set.&lt;/li&gt;
&lt;li&gt;Server Islands: Astro now supports server-rendered components within static pages, enabling hybrid rendering for dynamic interactivity without sacrificing performance.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
// Path: src/pages/islands-example.astro

import StaticHeader from '../components/StaticHeader.astro';
import DynamicCounter from '../components/DynamicCounter.jsx';
import HeavyDataComponent from '../components/HeavyDataComponent.jsx';
---

&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Islands Architecture Example&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;!-- Static, no JavaScript --&amp;gt;
    &amp;lt;StaticHeader title="Islands Architecture" /&amp;gt;

    &amp;lt;!-- Interactive, hydrated immediately --&amp;gt;
    &amp;lt;DynamicCounter client:load /&amp;gt;

    &amp;lt;!-- Interactive, hydrated only when visible --&amp;gt;
    &amp;lt;HeavyDataComponent client:visible /&amp;gt;

    &amp;lt;!-- Static content continues... --&amp;gt;
    &amp;lt;footer&amp;gt;
      &amp;lt;p&amp;gt;© 2025 My Website&amp;lt;/p&amp;gt;
    &amp;lt;/footer&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Content Layer API: Expanded Content Collections allow seamless integration with external APIs and databases, making Astro more versatile for dynamic content.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: src/content/config.ts

import { defineCollection, z } from 'astro:content';

// Define a schema for blog posts
const blogCollection = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    publishDate: z.date(),
    author: z.string(),
    featured: z.boolean().default(false),
    tags: z.array(z.string()).default([])
  })
});

// Export collections
export const collections = {
  'blog': blogCollection
};

// src/pages/blog/[...slug].astro
---
import { getCollection, getEntry } from 'astro:content';

// Generate paths at build time
export async function getStaticPaths() {
  const blogEntries = await getCollection('blog');
  return blogEntries.map(entry =&amp;gt; ({
    params: { slug: entry.slug },
    props: { entry }
  }));
}

const { entry } = Astro.props;
const { Content } = await entry.render();
---

&amp;lt;article&amp;gt;
  &amp;lt;h1&amp;gt;{entry.data.title}&amp;lt;/h1&amp;gt;
  &amp;lt;p&amp;gt;By {entry.data.author} on {entry.data.publishDate.toLocaleDateString()}&amp;lt;/p&amp;gt;
  &amp;lt;Content /&amp;gt;
&amp;lt;/article&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Astro DB: Built-in database management powered by Drizzle, enabling full-stack capabilities for more complex applications.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: db/schema.ts

import { defineDb, defineTable, column } from 'astro:db';

export const Users = defineTable({
  columns: {
    id: column.number({ primaryKey: true }),
    name: column.text(),
    email: column.text({ unique: true }),
    created_at: column.date()
  }
});

export default defineDb({
  tables: { Users }
});

// src/pages/api/users.ts
import { db } from 'astro:db';
import { Users } from '../../db/schema';

export async function GET() {
  const users = await db.select().from(Users);
  return new Response(JSON.stringify(users), {
    headers: { 'Content-Type': 'application/json' }
  });
}

export async function POST({ request }) {
  const { name, email } = await request.json();

  const user = await db.insert(Users).values({
    name,
    email,
    created_at: new Date()
  }).returning();

  return new Response(JSON.stringify(user), {
    status: 201,
    headers: { 'Content-Type': 'application/json' }
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Remix
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Routes: Like other frameworks, Remix allows developers to manage the different routes of their web projects using JavaScript/TypeScript files that contain handler functions. We can generate routes on our website to create files that follow the file system hierarchy of our projects, creating analog URLs for our pages. Remix routes work using the partial routing feature provided by React-Router.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// File-based routing in Remix

// Path: app/routes/_layout.tsx - Parent layout

import { Outlet, Link } from '@remix-run/react';

export default function Layout() {
  return (
    &amp;lt;div className="app-container"&amp;gt;
      &amp;lt;header&amp;gt;
        &amp;lt;nav&amp;gt;
          &amp;lt;Link to="/"&amp;gt;Home&amp;lt;/Link&amp;gt;
          &amp;lt;Link to="/about"&amp;gt;About&amp;lt;/Link&amp;gt;
          &amp;lt;Link to="/blog"&amp;gt;Blog&amp;lt;/Link&amp;gt;
        &amp;lt;/nav&amp;gt;
      &amp;lt;/header&amp;gt;

      &amp;lt;main&amp;gt;
        &amp;lt;Outlet /&amp;gt; {/* Child routes render here */}
      &amp;lt;/main&amp;gt;

      &amp;lt;footer&amp;gt;© 2025 My Remix App&amp;lt;/footer&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// app/routes/_layout.about.tsx - About page
export default function About() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;About Us&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Learn more about our company...&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// app/routes/_layout.blog.tsx - Blog index
export default function BlogIndex() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Blog&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Read our latest articles&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// app/routes/_layout.blog.$slug.tsx - Dynamic blog post route
import { useParams } from '@remix-run/react';

export default function BlogPost() {
  const { slug } = useParams();
  return &amp;lt;h1&amp;gt;Blog Post: {slug}&amp;lt;/h1&amp;gt;;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Nested components: Remix allows you to manage nested pages and components. We can create a file to handle a certain route and, at the same level in the file system, a folder with the same name. All the files we create inside that folder will be nested components of the parent route instead of different pages.&lt;/li&gt;
&lt;li&gt;Error Handling: Nested components bring another benefit: if an error occurs while rendering a certain component, it doesn’t affect the other nested parts of the page.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/routes/dashboard.tsx - Parent dashboard route

import { Outlet } from '@remix-run/react';

export default function Dashboard() {
  return (
    &amp;lt;div className="dashboard"&amp;gt;
      &amp;lt;h1&amp;gt;Dashboard&amp;lt;/h1&amp;gt;
      &amp;lt;nav&amp;gt;
        &amp;lt;Link to="/dashboard/stats"&amp;gt;Stats&amp;lt;/Link&amp;gt;
        &amp;lt;Link to="/dashboard/settings"&amp;gt;Settings&amp;lt;/Link&amp;gt;
      &amp;lt;/nav&amp;gt;
      &amp;lt;div className="dashboard-content"&amp;gt;
        &amp;lt;Outlet /&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// app/routes/dashboard.stats.tsx - Stats page with error boundary
import { useLoaderData } from '@remix-run/react';

export async function loader() {
  // Potentially could fail
  const stats = await fetchUserStats();
  return { stats };
}

// This only affects this route, not parent or siblings
export function ErrorBoundary() {
  return (
    &amp;lt;div className="error-container"&amp;gt;
      &amp;lt;h2&amp;gt;Error loading stats&amp;lt;/h2&amp;gt;
      &amp;lt;p&amp;gt;There was a problem loading your statistics.&amp;lt;/p&amp;gt;
      &amp;lt;button&amp;gt;Try again&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default function Stats() {
  const { stats } = useLoaderData();
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h2&amp;gt;Your Statistics&amp;lt;/h2&amp;gt;
      &amp;lt;div className="stats-grid"&amp;gt;
        {Object.entries(stats).map(([key, value]) =&amp;gt; (
          &amp;lt;div key={key} className="stat-card"&amp;gt;
            &amp;lt;h3&amp;gt;{key}&amp;lt;/h3&amp;gt;
            &amp;lt;p&amp;gt;{value}&amp;lt;/p&amp;gt;
          &amp;lt;/div&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Forms: As Remix focuses on web standards, it handles forms using native methods (POST, PUT, DELETE, PATCH) instead of JavaScript.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// app/routes/products.$id.tsx - Edit product form
import { Form, useLoaderData, useActionData, redirect } from '@remix-run/react';
import { json } from '@remix-run/node';
import { getProduct, updateProduct } from '~/models/product.server';

export async function loader({ params }) {
  const product = await getProduct(params.id);
  if (!product) {
    throw new Response("Product not found", { status: 404 });
  }
  return json({ product });
}

export async function action({ request, params }) {
  const formData = await request.formData();
  const name = formData.get('name');
  const price = parseFloat(formData.get('price'));

  const errors = {};
  if (!name) errors.name = "Name is required";
  if (isNaN(price) || price &amp;lt;= 0) errors.price = "Price must be a positive number";

  if (Object.keys(errors).length &amp;gt; 0) {
    return json({ errors });
  }

  await updateProduct(params.id, { name, price });
  return redirect('/products');
}

export default function EditProduct() {
  const { product } = useLoaderData();
  const actionData = useActionData();

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Edit Product: {product.name}&amp;lt;/h1&amp;gt;

      &amp;lt;Form method="post"&amp;gt;
        &amp;lt;div&amp;gt;
          &amp;lt;label&amp;gt;
            Name:
            &amp;lt;input name="name" defaultValue={product.name} /&amp;gt;
          &amp;lt;/label&amp;gt;
          {actionData?.errors?.name &amp;amp;&amp;amp; &amp;lt;p className="error"&amp;gt;{actionData.errors.name}&amp;lt;/p&amp;gt;}
        &amp;lt;/div&amp;gt;

        &amp;lt;div&amp;gt;
          &amp;lt;label&amp;gt;
            Price:
            &amp;lt;input name="price" type="number" step="0.01" defaultValue={product.price} /&amp;gt;
          &amp;lt;/label&amp;gt;
          {actionData?.errors?.price &amp;amp;&amp;amp; &amp;lt;p className="error"&amp;gt;{actionData.errors.price}&amp;lt;/p&amp;gt;}
        &amp;lt;/div&amp;gt;

        &amp;lt;div className="actions"&amp;gt;
          &amp;lt;button type="submit"&amp;gt;Save Changes&amp;lt;/button&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/Form&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Loaders and Actions: Remix provides two different types of functions to create server-side dynamic content. The loader functions handle GET HTTP requests in the server, mainly used to get data from different sources.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/routes/products.tsx - Loader and Action example

import { json, redirect } from '@remix-run/node';
import { useLoaderData, Form } from '@remix-run/react';
import { getProducts, createProduct } from '~/models/products.server';

// Loader for GET requests
export async function loader() {
  const products = await getProducts();
  return json({ products });
}

// Action for POST/PUT/DELETE requests
export async function action({ request }) {
  const formData = await request.formData();
  const intent = formData.get('intent');

  if (intent === 'create') {
    const name = formData.get('name');
    const price = parseFloat(formData.get('price'));

    await createProduct({ name, price });
    return redirect('/products');
  }

  return json({ error: 'Invalid intent' });
}

export default function Products() {
  const { products } = useLoaderData();

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;

      &amp;lt;h2&amp;gt;Add New Product&amp;lt;/h2&amp;gt;
      &amp;lt;Form method="post"&amp;gt;
        &amp;lt;input type="hidden" name="intent" value="create" /&amp;gt;
        &amp;lt;input name="name" placeholder="Product name" required /&amp;gt;
        &amp;lt;input name="price" type="number" step="0.01" placeholder="Price" required /&amp;gt;
        &amp;lt;button type="submit"&amp;gt;Add Product&amp;lt;/button&amp;gt;
      &amp;lt;/Form&amp;gt;

      &amp;lt;h2&amp;gt;Product List&amp;lt;/h2&amp;gt;
      &amp;lt;ul&amp;gt;
        {products.map(product =&amp;gt; (
          &amp;lt;li key={product.id}&amp;gt;
            {product.name} - ${product.price.toFixed(2)}
          &amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Static Site Generation (SSG): Remix now supports SSG, allowing developers to pre-render pages at build time. This feature bridges the gap between Remix and frameworks like Next.js.&lt;/li&gt;
&lt;li&gt;Enhanced Data Fetching: Optimized loaders and actions for parallel data fetching, reducing load times for complex applications.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Parallel data fetching in Remix
export async function loader() {
  // Fetch multiple data sources in parallel
  const [products, categories, featuredItems] = await Promise.all([
    getProducts(),
    getCategories(),
    getFeaturedItems()
  ]);

  return json({
    products,
    categories,
    featuredItems
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Next.js
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Async Components &amp;amp; Data Fetching: Async components are a new technique for obtaining data for server-rendered components introduced in Next.js 13. We can render async components using Promises with async and await.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/dashboard/page.js - Async Server Component

async function fetchDashboardData() {
  const res = await fetch('https://api.example.com/dashboard', {
    next: { revalidate: 60 } // Revalidate every 60 seconds
  });

  if (!res.ok) {
    throw new Error('Failed to fetch dashboard data');
  }

  return res.json();
}

export default async function DashboardPage() {
  // Data is fetched on the server during rendering
  const data = await fetchDashboardData();

  return (
    &amp;lt;div className="dashboard"&amp;gt;
      &amp;lt;h1&amp;gt;Dashboard&amp;lt;/h1&amp;gt;
      &amp;lt;div className="stats-grid"&amp;gt;
        &amp;lt;div className="stat-card"&amp;gt;
          &amp;lt;h2&amp;gt;Total Users&amp;lt;/h2&amp;gt;
          &amp;lt;p className="stat-value"&amp;gt;{data.totalUsers.toLocaleString()}&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="stat-card"&amp;gt;
          &amp;lt;h2&amp;gt;Active Subscriptions&amp;lt;/h2&amp;gt;
          &amp;lt;p className="stat-value"&amp;gt;{data.activeSubscriptions.toLocaleString()}&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div className="stat-card"&amp;gt;
          &amp;lt;h2&amp;gt;Revenue&amp;lt;/h2&amp;gt;
          &amp;lt;p className="stat-value"&amp;gt;${data.revenue.toLocaleString()}&amp;lt;/p&amp;gt;
        &amp;lt;/div&amp;gt;
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;React Server Components: Server components enable us to execute and render React components on the server side, resulting in faster delivery, a smaller JavaScript bundle, and lower client-side rendering costs.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/products/[id]/page.js - Server Component

import { notFound } from 'next/navigation';
import AddToCartButton from '@/components/AddToCartButton'; // Client Component
import ProductReviews from '@/components/ProductReviews'; // Server Component

async function getProduct(id) {
  const res = await fetch(`https://api.example.com/products/${id}`);
  if (!res.ok) return null;
  return res.json();
}

export default async function ProductPage({ params }) {
  const product = await getProduct(params.id);

  if (!product) {
    notFound();
  }

  return (
    &amp;lt;div className="product-page"&amp;gt;
      &amp;lt;h1&amp;gt;{product.name}&amp;lt;/h1&amp;gt;
      &amp;lt;p className="price"&amp;gt;${product.price.toFixed(2)}&amp;lt;/p&amp;gt;
      &amp;lt;div className="description"&amp;gt;{product.description}&amp;lt;/div&amp;gt;

      {/* Client Component - will be hydrated on the client */}
      &amp;lt;AddToCartButton productId={product.id} /&amp;gt;

      {/* Server Component - no client JS needed */}
      &amp;lt;ProductReviews productId={product.id} /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// components/AddToCartButton.js - Client Component
'use client';

import { useState } from 'react';

export default function AddToCartButton({ productId }) {
  const [isAdding, setIsAdding] = useState(false);

  async function handleAddToCart() {
    setIsAdding(true);
    await addToCart(productId);
    setIsAdding(false);
  }

  return (
    &amp;lt;button 
      onClick={handleAddToCart} 
      disabled={isAdding}
      className="add-to-cart-button"
    &amp;gt;
      {isAdding ? 'Adding...' : 'Add to Cart'}
    &amp;lt;/button&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;app/ Directory for File-Based Routing: Routes are defined using the structure of your project directory. By placing an entry point in the app directory, you can create a new route. This feature is now stable and fully supported for production use.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Next.js App Router structure example
// app/page.js - Homepage
export default function HomePage() {
  return &amp;lt;h1&amp;gt;Welcome to our website&amp;lt;/h1&amp;gt;;
}

// app/about/page.js - About page (/about)
export default function AboutPage() {
  return &amp;lt;h1&amp;gt;About Us&amp;lt;/h1&amp;gt;;
}

// app/blog/[slug]/page.js - Dynamic blog post page (/blog/*)
export default function BlogPost({ params }) {
  return &amp;lt;h1&amp;gt;Blog Post: {params.slug}&amp;lt;/h1&amp;gt;;
}

// app/api/products/route.js - API route (/api/products)
export async function GET(request) {
  const products = await fetchProducts();
  return Response.json(products);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Lightning Fast Bundling: &lt;a href="https://nextjs.org/docs/app/api-reference/turbopack" rel="noopener noreferrer"&gt;Turbopack&lt;/a&gt;, introduced with Next.js 13, is now stable and offers lightning-fast bundling, significantly reducing build times for large projects.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: next.config.js - Enabling Turbopack

/** @type {import('next').NextConfig} */
const nextConfig = {
  // Enable Turbopack for development
  experimental: {
    turbo: true,
  }
};

module.exports = nextConfig;

// Using with npm scripts in package.json
{
  "scripts": {
    "dev": "next dev --turbo",
    "build": "next build",
    "start": "next start"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Built-in CSS and Sass support: Support for any CSS-in-JS library.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Using CSS Modules in Next.js

// Path: components/Button.module.css

.button {
  background: blue;
  color: white;
  padding: 8px 16px;
  border-radius: 4px;
  border: none;
  cursor: pointer;
}

.button:hover {
  background: darkblue;
}

// components/Button.js
import styles from './Button.module.css';

export default function Button({ children, onClick }) {
  return (
    &amp;lt;button className={styles.button} onClick={onClick}&amp;gt;
      {children}
    &amp;lt;/button&amp;gt;
  );
}

// Global CSS in app/globals.css
body {
  font-family: system-ui, sans-serif;
  margin: 0;
  padding: 0;
}

// Using in app/layout.js
import './globals.css';

export default function RootLayout({ children }) {
  return (
    &amp;lt;html lang="en"&amp;gt;
      &amp;lt;body&amp;gt;{children}&amp;lt;/body&amp;gt;
    &amp;lt;/html&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Static Exports: Next.js allows you to export a fully static site from your app using the next export command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: next.config.js - Static export configuration

/** @type {import('next').NextConfig} */
const nextConfig = {
  output: 'export',
  // Optional: Change the output directory
  distDir: 'out',
  // Optional: Add basePath for deployment to a subdirectory
  basePath: '/docs'
};

module.exports = nextConfig;

// package.json
{
  "scripts": {
    "build": "next build",
    "export": "next export" // For older Next.js versions
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Advanced Server Actions: Next.js 14 introduces server actions for handling data mutations, simplifying backend logic without requiring separate API routes.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/actions.js - Server Actions

'use server';

import { cookies } from 'next/headers';
import { revalidatePath } from 'next/cache';
import { db } from '@/lib/db';

export async function addToCart(formData) {
  const productId = formData.get('productId');
  const quantity = parseInt(formData.get('quantity') || '1');

  // Get user from cookie
  const userId = cookies().get('userId')?.value;
  if (!userId) {
    throw new Error('User not authenticated');
  }

  try {
    await db.cart.upsert({
      where: { 
        userId_productId: {
          userId,
          productId
        }
      },
      update: {
        quantity: { increment: quantity }
      },
      create: {
        userId,
        productId,
        quantity
      }
    });

    // Revalidate cart page
    revalidatePath('/cart');

    return { success: true };
  } catch (error) {
    return { success: false, error: error.message };
  }
}

// app/products/[id]/page.js
import { addToCart } from '@/app/actions';

export default function ProductPage({ params }) {
  // ...product details

  return (
    &amp;lt;div&amp;gt;
      {/* ... */}
      &amp;lt;form action={addToCart}&amp;gt;
        &amp;lt;input type="hidden" name="productId" value={params.id} /&amp;gt;
        &amp;lt;input type="number" name="quantity" min="1" defaultValue="1" /&amp;gt;
        &amp;lt;button type="submit"&amp;gt;Add to Cart&amp;lt;/button&amp;gt;
      &amp;lt;/form&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Enhanced Caching: Improved caching mechanisms, including stale-while-revalidate (SWR), ensure faster content delivery and better user experiences.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Using SWR for client-side data fetching
'use client';

import useSWR from 'swr';

// Reusable fetcher function
const fetcher = (...args) =&amp;gt; fetch(...args).then(res =&amp;gt; res.json());

export default function ProductList() {
  const { data, error, isLoading } = useSWR('/api/products', fetcher, {
    // Revalidate every 10 seconds
    refreshInterval: 10000,
    // Keep data even when fetching fails
    revalidateOnError: false
  });

  if (isLoading) return &amp;lt;div&amp;gt;Loading products...&amp;lt;/div&amp;gt;;
  if (error) return &amp;lt;div&amp;gt;Error loading products&amp;lt;/div&amp;gt;;

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Products&amp;lt;/h1&amp;gt;
      &amp;lt;ul&amp;gt;
        {data.map(product =&amp;gt; (
          &amp;lt;li key={product.id}&amp;gt;{product.name}&amp;lt;/li&amp;gt;
        ))}
      &amp;lt;/ul&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Hydration
&lt;/h3&gt;

&lt;p&gt;Hydration is a client-side JavaScript technique for converting a static HTML page into a dynamic page. This provides a pleasant user experience by displaying a rendered component on the page but with attached event handlers. Hydration occurs before user interaction on static pages. The user experience suffers as a result.&lt;/p&gt;

&lt;h3&gt;
  
  
  Astro
&lt;/h3&gt;

&lt;p&gt;Astro handles hydration through a method known as partial hydration. This approach loads individual components only when needed, leaving the rest of the page as static HTML. The island architecture is central to this process, as it ensures that only the necessary JavaScript is loaded, improving performance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;---
// Path: src/pages/hydration-example.astro

import StaticComponent from '../components/StaticComponent.astro';
import InteractiveCounter from '../components/InteractiveCounter.jsx';
import LazyLoadedComponent from '../components/LazyLoadedComponent.jsx';
import HeavyComponent from '../components/HeavyComponent.jsx';
---

&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Hydration Example&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;!-- Static component, no JavaScript --&amp;gt;
    &amp;lt;StaticComponent /&amp;gt;

    &amp;lt;!-- Hydration strategies --&amp;gt;
    &amp;lt;!-- 1. Hydrate immediately on page load --&amp;gt;
    &amp;lt;InteractiveCounter client:load /&amp;gt;

    &amp;lt;!-- 2. Hydrate when component is visible in viewport --&amp;gt;
    &amp;lt;LazyLoadedComponent client:visible /&amp;gt;

    &amp;lt;!-- 3. Hydrate after page load, when browser is idle --&amp;gt;
    &amp;lt;HeavyComponent client:idle /&amp;gt;

    &amp;lt;!-- 4. Hydrate only when media query matches --&amp;gt;
    &amp;lt;div client:media="(max-width: 768px)"&amp;gt;
      This only hydrates on mobile devices
    &amp;lt;/div&amp;gt;

    &amp;lt;!-- 5. Don't hydrate at all on the server, render only on client --&amp;gt;
    &amp;lt;div client:only="react"&amp;gt;
      This renders only on the client
    &amp;lt;/div&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In most cases, Astro websites load significantly faster than Next.js websites because Astro automatically strips unnecessary JavaScript and hydrates only the components that require interactivity.&lt;/li&gt;
&lt;li&gt;By default, Astro delivers static HTML with minimal JavaScript, resulting in faster page loads and better performance for content-heavy sites.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Next.js
&lt;/h3&gt;

&lt;p&gt;Next.js has evolved its hydration strategy with the introduction of React Server Components (RSCs) and Selective Hydration in Next.js 14. While it traditionally required full-page hydration, it now supports granular hydration for interactive components, reducing the amount of JavaScript sent to the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/page.js - Server Component

// This doesn't require client-side JS
export default function HomePage() {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Welcome to our site&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;This server component requires no client-side JavaScript&amp;lt;/p&amp;gt;

      {/* Client components are selectively hydrated */}
      &amp;lt;ClientSideInteractive /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// components/ClientSideInteractive.js
'use client'; // Mark as client component

import { useState } from 'react';

export default function ClientSideInteractive() {
  // Client-side state and interactivity
  const [count, setCount] = useState(0);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;p&amp;gt;This component is hydrated with JavaScript&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;Count: {count}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={() =&amp;gt; setCount(count + 1)}&amp;gt;
        Increment
      &amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Next.js allows developers to hydrate only the interactive parts of a page, improving performance for static-heavy content.&lt;/li&gt;
&lt;li&gt;Next.js continues to support zero-JavaScript pages through Static Site Generation (SSG) and Incremental Static Regeneration (ISR).&lt;/li&gt;
&lt;li&gt;Unlike Astro’s island architecture, which hydrates individual components by default, Next.js still prioritizes full-page hydration but offers selective hydration as an experimental feature for optimization.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Remix
&lt;/h3&gt;

&lt;p&gt;Remix does not support partial hydration. There are assumptions that Remix will function with the new React 19 suspense features, but Remix does not allow partial hydration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: app/entry.client.jsx - Client-side hydration in Remix

import { RemixBrowser } from '@remix-run/react';
import { startTransition, StrictMode } from 'react';
import { hydrateRoot } from 'react-dom/client';

// The entire app is hydrated at once
startTransition(() =&amp;gt; {
  hydrateRoot(
    document,
    &amp;lt;StrictMode&amp;gt;
      &amp;lt;RemixBrowser /&amp;gt;
    &amp;lt;/StrictMode&amp;gt;
  );
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Loading Speed
&lt;/h3&gt;

&lt;p&gt;The loading speed plays an important role in web application, because it directly affects user experience, SEO performance and system performance. The loading speed optimization techniques of Astro, Remix and Next.js depend on their specific architectural methods and built-in features. Let’s take a look at how these frameworks handle performance and what makes them fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Astro
&lt;/h3&gt;

&lt;p&gt;Astro is fast, basically designed for speed. The island architecture strategy aids in SEO because it ranks highly on on-site search engines. It offers a fantastic user experience and has less boilerplate code. It supports most CSS libraries and frameworks and provides a great base for style support.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: astro.config.mjs - Performance optimizations

import { defineConfig } from 'astro/config';
import image from '@astrojs/image';
import compress from 'astro-compress';

export default defineConfig({
  // Image optimization
  integrations: [
    image({
      serviceEntryPoint: '@astrojs/image/sharp'
    }),
    // Compress HTML, CSS, and JavaScript
    compress()
  ],

  // Enable view transitions for smooth navigation
  experimental: {
    viewTransitions: true
  },

  // CSS optimizations
  vite: {
    build: {cssCodeSplit: true,
      cssMinify: true,
    }
  }
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Remix
&lt;/h3&gt;

&lt;p&gt;Remix claims that data retrieval is sped up by loading data in parallel on the server. Remix can prerender pages on the server because it supports server-side rendering. In contrast to Remix, Astro provides a statically-bundled HTML file with minimal to no JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why the Remix rewrite is fast?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Instead of caching documents with SSG or SWR, this version caches data at the edge in Redis.&lt;/li&gt;
&lt;li&gt;It runs the application at the edge too with Fly.io.&lt;/li&gt;
&lt;li&gt;Quick image optimization Resource Route that writes to a persistent volume.&lt;/li&gt;
&lt;li&gt;It’s its own CDN. This might have been difficult to build a few years ago, but the server landscape has changed significantly in the past few years and is only getting better.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: remix.config.js - Performance configuration

/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
  // Deploy to edge runtime
  serverBuildTarget: "vercel",
  server: process.env.NODE_ENV === "development" ? undefined : "./server.js",
  ignoredRouteFiles: ["**/.*"],
  // Optimize JS output
  future: {
    v2_routeConvention: true,
    v2_meta: true,
    v2_errorBoundary: true,
    v2_normalizeFormMethod: true,
  },
  // Caching strategy
  serverDependenciesToBundle: "all",

  // Custom Resource Routes for optimized assets
  routes: function(defineRoutes) {
    return defineRoutes((route) =&amp;gt; {
      route(
        "/resources/image/:width/:height/:src",
        "routes/resources/image.tsx"
      );
    });
  }
};

// routes/resources/image.tsx - Image optimization route
import { LoaderFunction } from "@remix-run/node";
import { optimizeImage } from "~/utils/images.server";

export const loader: LoaderFunction = async ({ params, request }) =&amp;gt; {
  const { width, height, src } = params;
  const format = new URL(request.url).searchParams.get("format") || "webp";

  try {
    const { buffer, contentType } = await optimizeImage({
      src: src as string,
      width: parseInt(width as string),
      height: parseInt(height as string),
      format,
    });

    return new Response(buffer, {
      headers: {
        "Content-Type": contentType,
        "Cache-Control": "public, max-age=31536000, immutable",
      },
    });
  } catch (error) {
    return new Response("Image optimization failed", { status: 500 });
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Why the Remix port is fast?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Remix now supports Static Site Generation (SSG), allowing developers to pre-render pages at build time.&lt;/li&gt;
&lt;li&gt;The result is the same: a static document at the edge (even on the same CDN, Vercel’s). The difference is how the documents get there. Instead of fetching all the data and rendering the pages to static documents at build/deploy time, the cache is primed when you get traffic.&lt;/li&gt;
&lt;li&gt;Documents are served from the cache and revalidated in the background for the next visitor.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Parallel data fetching for improved performance

// Path: app/routes/dashboard.tsx

import { json } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';
import { getUser, getStats, getActivities, getNotifications } from '~/models/dashboard.server';

export async function loader({ request }) {
  const userId = await getUserId(request);

  // Fetch all data in parallel for improved performance
  const [user, stats, activities, notifications] = await Promise.all([
    getUser(userId),
    getStats(userId),
    getActivities(userId),
    getNotifications(userId)
  ]);

  return json({
    user,
    stats,
    activities,
    notifications
  });
}

export default function Dashboard() {
  const { user, stats, activities, notifications } = useLoaderData();
  // Render dashboard UI with fetched data...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Next.js
&lt;/h3&gt;

&lt;p&gt;Next.js boasts of its server-side rendering and static builds features. Next.js also includes several pre-built techniques for data retrieval.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why Next.js is fast?
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;The homepage uses Static Site Generation (SSG) with getStaticProps.&lt;/li&gt;
&lt;li&gt;At build time, Next.js pulls data from Shopify, renders a page to an HTML file, and puts it in the public directory.&lt;/li&gt;
&lt;li&gt;When the site is deployed, the static file is served at the edge (out of Vercel’s CDN) instead of hitting an origin server at a single location.&lt;/li&gt;
&lt;li&gt;When a request comes in, the CDN serves the file.&lt;/li&gt;
&lt;li&gt;Data loading and rendering have already been done ahead of time, so the visitor doesn’t pay the download + render cost.&lt;/li&gt;
&lt;li&gt;The CDN is distributed globally, close to users (this is “the edge”), so requests for statically generated documents don’t have to travel to a single origin server.&lt;/li&gt;
&lt;li&gt;Next.js now supports React Server Components (RSCs) and Selective Hydration, reducing the amount of JavaScript sent to the client and improving performance for dynamic content.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Path: pages/index.js - Static Site Generation

export default function HomePage({ products, categories }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;Welcome to our store&amp;lt;/h1&amp;gt;
      &amp;lt;div className="product-grid"&amp;gt;
        {products.map(product =&amp;gt; (
          &amp;lt;ProductCard key={product.id} product={product} /&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

// This runs at build time in production
export async function getStaticProps() {
  // Fetch data from CMS, database, or API
  const products = await fetchFeaturedProducts();
  const categories = await fetchCategories();

  return {
    props: {
      products,
      categories
    },
    // Re-generate at most once per hour
    revalidate: 3600
  };
}

// Incremental Static Regeneration example
// pages/products/[id].js
export default function Product({ product }) {
  // Render product details...
}

export async function getStaticPaths() {
  // Pre-render only the most popular products
  const popularProducts = await fetchPopularProducts();

  return {
    paths: popularProducts.map(product =&amp;gt; ({
      params: { id: product.id.toString() }
    })),
    // Enable ISR for products not generated at build time
    fallback: 'blocking'
  };
}

export async function getStaticProps({ params }) {
  const product = await fetchProduct(params.id);

  return {
    props: { product },
    revalidate: 60 // Update every minute if requested
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SSR
&lt;/h3&gt;

&lt;p&gt;Server-side rendering (SSR) refers to the process of pre-rendering client-side single-page applications on the server and then sending a fully rendered page on user request. Server-side rendering is essential because server-side rendered applications are SEO-friendly and fast. Apps that support server-side rendering are usually due to their reduced page load time.&lt;/p&gt;

&lt;p&gt;Astro, Remix, and Next.js offer server-side rendering (SSR) to generate the markup and content of our pages from the web server before sending it to the client.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Astro SSR configuration

// Path: astro.config.mjs
import { defineConfig } from 'astro/config';
import nodejs from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: nodejs({
    mode: 'standalone'
  })
});

// Next.js SSR example
// pages/products/[id].js
export default function Product({ product }) {
  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;{product.name}&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;{product.description}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;${product.price}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export async function getServerSideProps({ params, req, res }) {
  // This runs on every request
  const product = await fetchProduct(params.id);

  // Set cache headers
  res.setHeader(
    'Cache-Control',
    'public, s-maxage=10, stale-while-revalidate=59'
  );

  return {
    props: { product }
  };
}

// Remix SSR example
// app/routes/products.$id.jsx
import { json } from '@remix-run/node';
import { useLoaderData } from '@remix-run/react';

export async function loader({ params, request }) {
  const product = await fetchProduct(params.id);

  return json(
    { product },
    {
      headers: {
        'Cache-Control': 'max-age=300, s-maxage=3600'
      }
    }
  );
}

export default function Product() {
  const { product } = useLoaderData();

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;{product.name}&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;{product.description}&amp;lt;/p&amp;gt;
      &amp;lt;p&amp;gt;${product.price}&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Ease Of Use
&lt;/h3&gt;

&lt;p&gt;Next.js, Astro, and Remix have a short learning curve. Because they are all based on React, you only need a basic understanding of React to set up Next.js, Astro, and Remix. They all feature developer-friendly documentation, making them simple to use and configure.&lt;/p&gt;

&lt;p&gt;Next includes the create-next-app CLI command for quickly launching a Next.js application. For bootstrapping an Astro application, use the create astro@latest command, whereas Remix uses the create-remix@latest command for Remix apps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Create a new Next.js app
npx create-next-app@latest my-next-app

# Create a new Astro app
npm create astro@latest my-astro-app

# Create a new Remix app
npx create-remix@latest my-remix-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;p&gt;We looked at Astro, a highly performant library for shipping no JavaScript code, Remix, a framework for handling client-side and server-side code, and Next.js, which includes data fetching methods such as ISR, CSR, SSG, and SSR.&lt;/p&gt;

&lt;p&gt;We looked at key features, loading speed, hydration, server-side rendering, and ease of use. This allows you to select the framework to utilize for your projects. It’s not about which framework is better but which solves your problem best.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Framework selection helper
function recommendFramework(requirements) {
  // Content-heavy site with minimal interactivity
  if (requirements.contentFocused &amp;amp;&amp;amp; requirements.minimalInteractivity) {
    return "Astro";
  }

  // Full-stack application with forms and data mutations
  if (requirements.formHandling &amp;amp;&amp;amp; requirements.dataManagement) {
    return "Remix";
  }

  // Enterprise application with complex requirements
  if (requirements.enterprise &amp;amp;&amp;amp; requirements.ecosystem) {
    return "Next.js";
  }

  // General recommendation based on team experience
  return requirements.teamExperience || "Next.js";
}

// Example usage
console.log(recommendFramework({
  contentFocused: true,
  minimalInteractivity: true,
  teamExperience: "React"
})); // Output: "Astro"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you would like to start building with these frameworks, check out these resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://strapi.io/blog/how-to-build-a-blog-app-with-remix-and-strapi-cms" rel="noopener noreferrer"&gt;How to Build a Blog App with Remix and Strapi CMS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://strapi.io/blog/how-to-create-an-ssg-static-site-generation-application-with-strapi-webhooks-and-nextjs" rel="noopener noreferrer"&gt;How to Create an SSG (Static Site Generation) Application with Strapi Webhooks and NextJs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Continue discussing this topic further or connect with more people using Strapi on our &lt;a href="https://discord.com/invite/strapi" rel="noopener noreferrer"&gt;Discord community&lt;/a&gt;. It is a great place to share your thoughts, ask questions, and participate in live discussions.&lt;/p&gt;




</description>
      <category>programming</category>
      <category>nextjs</category>
      <category>strapi</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Polymorphism in Java</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Sat, 03 May 2025 09:04:30 +0000</pubDate>
      <link>https://forem.com/masteringbackend/polymorphism-in-java-387j</link>
      <guid>https://forem.com/masteringbackend/polymorphism-in-java-387j</guid>
      <description>&lt;p&gt;Polymorphism is a fundamental concept in object-oriented programming (OOP). Since Java is an OOP language, it fully supports polymorphism, which allows developers to write more flexible, efficient, and reusable code.&lt;/p&gt;

&lt;p&gt;The term &lt;em&gt;polymorphism&lt;/em&gt; comes from two Greek words: &lt;em&gt;poly&lt;/em&gt; (meaning “many”) and &lt;em&gt;morph&lt;/em&gt; (meaning “form”). So, &lt;strong&gt;polymorphism&lt;/strong&gt; literally means “many forms,” a single object can take on multiple forms or behaviors.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fylo2sm5anwtbg0szyjiq.png" class="article-body-image-wrapper"&gt;&lt;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%2Fylo2sm5anwtbg0szyjiq.png" alt="Polymorphism explained" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example -&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Consider a person named Ayush. At home, he acts as a &lt;strong&gt;teacher&lt;/strong&gt; , helping his children study. At the office, he becomes an &lt;strong&gt;employee&lt;/strong&gt; , fulfilling tasks assigned by his manager. On weekends, he participates in cultural programs as a  &lt;strong&gt;dancer&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Though Ayush is one individual, his behavior changes based on the situation. Similarly, in Java, a single object can perform different behaviors depending on how it is used, which can be achieved through &lt;strong&gt;method overloading&lt;/strong&gt; or &lt;strong&gt;method overriding&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Types Of Polymorphism
&lt;/h3&gt;

&lt;p&gt;&lt;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%2F5cp66u4vjx7giqshqba9.png" class="article-body-image-wrapper"&gt;&lt;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%2F5cp66u4vjx7giqshqba9.png" alt="Polymorphism organogram" width="800" height="402"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Compile Time Polymorphism
&lt;/h3&gt;

&lt;p&gt;Compile-time polymorphism is also known as &lt;strong&gt;static&lt;/strong&gt; or &lt;strong&gt;early&lt;/strong&gt; binding. It occurs when the decision about which method to call is made at compile time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt;  — Method overloading&lt;/p&gt;

&lt;h3&gt;
  
  
  Run Time Polymorphism
&lt;/h3&gt;

&lt;p&gt;Run-time polymorphism is also known as &lt;strong&gt;dynamic or late&lt;/strong&gt; binding. It occurs when the decision about which method to call is made at run time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example&lt;/strong&gt; - Method Overriding&lt;/p&gt;

&lt;h3&gt;
  
  
  Compile Time vs Run Time Polymorphism
&lt;/h3&gt;

&lt;p&gt;&lt;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%2Flsbprmm142wc1pwswxcl.png" class="article-body-image-wrapper"&gt;&lt;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%2Flsbprmm142wc1pwswxcl.png" alt="compile vs run time polymorphism" width="800" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  What is Method Overloading?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Developing multiple methods with the same name by variation in the argument list is called method overloading.&lt;/li&gt;
&lt;li&gt;Variation in the argument lists means variation in the number of arguments, the datatype of the arguments, and the position of the arguments.&lt;/li&gt;
&lt;li&gt;Both &lt;strong&gt;static&lt;/strong&gt; and &lt;strong&gt;non-static&lt;/strong&gt; methods can be overloaded.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Two methods are said to be overloaded if both the method having same name but variation in arguments, such as the number of arguments, the datatype of the arguments, and the position of the arguments.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;returnType methodName(parameterType1 param1) {  
    // method body  
}

returnType methodName(parameterType1 param1, parameterType2 param2) {  
    // method body  
}

returnType methodName(parameterType1 param1, parameterType2 param2, parameterType3 param3) {  
    // method body  
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class MasterBackend {

    // sum method with two int parameters
    public int sum(int a, int b) {
        return a + b;
    }

    // sum method with three int parameters
    public int sum(int a, int b, int c) {
        return a + b + c;
    }

    // sum method with two double parameters
    public double sum(double a, double b) {
        return a + b;
    }

    public static void main(String[] args) {
        MasterBackend obj = new MasterBackend();

        System.out.println("Sum of 10 and 20: " + obj.sum(10, 20));
        System.out.println("Sum of 10, 20 and 30: " + obj.sum(10, 20, 30));
        System.out.println("Sum of 10.5 and 20.5: " + obj.sum(10.5, 20.5));
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, in this example, inside the MasterBackend class, we develop several methods with the same name but variations in parameters. But all the methods perform the same operation, which is addition.&lt;/p&gt;

&lt;p&gt;In the first method, we add two Integer numbers, and in the second method, we add three Integer numbers; then, in the third method, we add two double numbers, that’s why we give the same name.&lt;/p&gt;

&lt;p&gt;By giving the same name, we can remember the method names easily, and compile-time polymorphism occurs when the decision about which method to call is made at compile time according to the parameters.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sum of 10 and 20: 30
Sum of 10, 20 and 30: 60
Sum of 10.5 and 20.5: 31.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What is Method Overriding?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Method overriding&lt;/strong&gt; is a mechanism that enables &lt;strong&gt;runtime polymorphism&lt;/strong&gt; in Java.&lt;/li&gt;
&lt;li&gt;It occurs when a &lt;strong&gt;subclass&lt;/strong&gt; provides a &lt;strong&gt;specific implementation&lt;/strong&gt; of a method that is already defined in its &lt;strong&gt;superclass&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inheritance&lt;/strong&gt; is essential for method overriding, as the method in the subclass must originate from a superclass.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;method signature&lt;/strong&gt; (name, parameters, and order) in the subclass must be &lt;strong&gt;identical&lt;/strong&gt; to that of the superclass.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static&lt;/strong&gt; and &lt;strong&gt;private&lt;/strong&gt; methods &lt;strong&gt;cannot be overridden&lt;/strong&gt; because:&lt;/li&gt;
&lt;li&gt;Method overriding is commonly used in &lt;strong&gt;abstract classes&lt;/strong&gt; and &lt;strong&gt;interfaces&lt;/strong&gt; , where child classes are required to provide specific implementations for abstract methods.&lt;/li&gt;
&lt;li&gt;The &lt;a class="mentioned-user" href="https://dev.to/override"&gt;@override&lt;/a&gt; annotation is used to:&lt;/li&gt;
&lt;li&gt;Indicate that a method is intended to override a superclass method.&lt;/li&gt;
&lt;li&gt;Help catch errors at &lt;strong&gt;compile time&lt;/strong&gt; if the method signature doesn’t match.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In simple terms:&lt;/p&gt;

&lt;p&gt;When a child (or subclass) is &lt;strong&gt;not satisfied&lt;/strong&gt; with the behavior of a method inherited from the parent (superclass), it can &lt;strong&gt;override&lt;/strong&gt; that method to provide a new implementation. This is known as &lt;strong&gt;method overriding&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Syntax:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Superclass
class SuperClass {
    returnType methodName(parameterType1 param1, parameterType2 param2) {
        // method body
    }
}

// Subclass
class SubClass extends SuperClass {
    @Override
    returnType methodName(parameterType1 param1, parameterType2 param2) {
        // overridden method body
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here, &lt;a class="mentioned-user" href="https://dev.to/override"&gt;@override&lt;/a&gt; annotation for better readability and compile-time checking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person {
    public void smoking() {
        System.out.println("Person may or may not smoke.");
    }
}

class Teenager extends Person {
    @Override
    public void smoking() {
        System.out.println("Teenager should avoid smoking.");
    }
}

// Main class
public class MasterBackend {
    public static void main(String[] args) {
        Person p1 = new Person();         
        Person p2 = new Teenager();       

        p1.smoking(); 
        p2.smoking();
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we have a superclass called Person and a subclass named Teenager. Both classes define a method with the same name and signature: smoking(). However, each class provides its own implementation.&lt;/p&gt;

&lt;p&gt;The Person class offers a general statement about smoking, while the Teenager class overrides the method to deliver a more specific message.&lt;/p&gt;

&lt;p&gt;We use the same method name because the action being performed is conceptually the same, communicating a message about smoking, but the behavior varies depending on the object type.&lt;/p&gt;

&lt;p&gt;This illustrates &lt;strong&gt;runtime polymorphism&lt;/strong&gt; , where the decision about which method to invoke is made based on the actual object instance rather than the reference type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Person may or may not smoke. 
Teenager should avoid smoking.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Example 2:
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Vehicle {
    void start() {
        System.out.println("The vehicle starts");
    }
}

class Car extends Vehicle {
    @Override
    void start() {
        System.out.println("The car starts with a key ignition");
    }
}

class Bike extends Vehicle {
    @Override
    void start() {
        System.out.println("The bike starts with a kick");
    }
}

public class Main {
    public static void main(String[] args) {
        Vehicle myVehicle = new Vehicle();
        myVehicle.start(); // Calls the start method in Vehicle

        Vehicle myCar = new Car();
        myCar.start(); // Calls the overridden start method in Car

        Vehicle myBike = new Bike();
        myBike.start(); // Calls the overridden start method in Bike
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, Vehicle is the superclass that defines a method named start(). The classes Car and Bike extend Vehicle and the start() method to provide behavior specific to their types.&lt;/p&gt;

&lt;p&gt;At runtime, the &lt;strong&gt;actual object type&lt;/strong&gt; (whether it's a Car, Bike, or Vehicle) determines which version of the start() method is executed.&lt;/p&gt;

&lt;p&gt;This demonstrates &lt;strong&gt;runtime polymorphism&lt;/strong&gt; , where method resolution is deferred until the program is running and depends on the &lt;strong&gt;object's actual class&lt;/strong&gt; , not the reference type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Output:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The vehicle starts 
The car starts with a key ignition 
The bike starts with a kick
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Overloading Vs Overriding
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Method Overloading
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Occurs within the same class&lt;/li&gt;
&lt;li&gt;Same method name but different parameter list&lt;/li&gt;
&lt;li&gt;Return type can be different (if the parameter list is different)&lt;/li&gt;
&lt;li&gt;No inheritance required&lt;/li&gt;
&lt;li&gt;Compile-time polymorphism (resolved at compile time)&lt;/li&gt;
&lt;li&gt;Increases code readability and reusability&lt;/li&gt;
&lt;li&gt;No @Overloding annotation used&lt;/li&gt;
&lt;li&gt;Method resolution happens by checking the method signature&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Method Overriding
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Occurs in a subclass (child class) only&lt;/li&gt;
&lt;li&gt;Same method name and same parameter list as in the superclass&lt;/li&gt;
&lt;li&gt;Return type must be the same or covariant&lt;/li&gt;
&lt;li&gt;Requires inheritance&lt;/li&gt;
&lt;li&gt;Runtime polymorphism (resolved at runtime)&lt;/li&gt;
&lt;li&gt;Used to provide a specific implementation of a method&lt;/li&gt;
&lt;li&gt;Uses &lt;a class="mentioned-user" href="https://dev.to/override"&gt;@override&lt;/a&gt; annotation (recommended)&lt;/li&gt;
&lt;li&gt;Method resolution depends on the object’s runtime type&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Frequently Asked Questions
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Can we override the static methods?
&lt;/h4&gt;

&lt;p&gt;No. We can’t override static methods because static methods will not be inherited by the subclass. And to achieve method overriding, inheritance is mandatory.&lt;/p&gt;

&lt;h4&gt;
  
  
  Can we overload the main method?
&lt;/h4&gt;

&lt;p&gt;Yes. We can overload the main method, but the JVM only takes that method which is having the String args[] as a parameter.&lt;/p&gt;

&lt;h4&gt;
  
  
  Can we override the main method?
&lt;/h4&gt;

&lt;p&gt;No. Because the main method is a static method and static method will not be inherited by the subclass. And to achieve method overriding, inheritance is mandatory.&lt;/p&gt;

&lt;h4&gt;
  
  
  Can we override the constructor?
&lt;/h4&gt;

&lt;p&gt;No. Because the constructor will not be inherited by a subclass. And to achieve method overriding, inheritance is mandatory.&lt;/p&gt;




&lt;h3&gt;
  
  
  Thank you for being a part of the community
&lt;/h3&gt;

&lt;p&gt;Before you go:&lt;/p&gt;

&lt;h4&gt;
  
  
  Whenever you’re ready
&lt;/h4&gt;

&lt;p&gt;There are 4 ways we can help you become a great backend engineer:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Platform:&lt;/strong&gt;&lt;/a&gt; Join thousands of backend engineers learning backend engineering. Build real-world backend projects, learn from expert-vetted courses and roadmaps, track your learnings and set schedules, and solve backend engineering tasks, exercises, and challenges.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://masteringbackend.com/academy?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;The MB Academy:&lt;/strong&gt;&lt;/a&gt; The “MB Academy” is a 6-month intensive Advanced Backend Engineering BootCamp to produce great backend engineers.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://backendweeky.dev?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;Join Backend Weekly:&lt;/strong&gt;&lt;/a&gt; If you like posts like this, you will absolutely enjoy our exclusive weekly newsletter, sharing exclusive backend engineering resources to help you become a great Backend Engineer.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://getbackendjobs.com?ref=medium" rel="noopener noreferrer"&gt;&lt;strong&gt;Get Backend Jobs:&lt;/strong&gt;&lt;/a&gt; Find over 2,000+ Tailored International Remote Backend Jobs or Reach 50,000+ backend engineers on the #1 Backend Engineering Job Board.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://masteringbackend.com/hubs/java-backend-development/polymorphism-in-java" rel="noopener noreferrer"&gt;&lt;em&gt;https://masteringbackend.com&lt;/em&gt;&lt;/a&gt; &lt;em&gt;on May 3, 2025.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>tutorial</category>
      <category>beginners</category>
      <category>backend</category>
      <category>webdev</category>
    </item>
    <item>
      <title>SEO-Friendly Pagination Solution for Large Websites</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Wed, 30 Apr 2025 15:48:49 +0000</pubDate>
      <link>https://forem.com/strapi/seo-friendly-pagination-solution-for-large-websites-1ago</link>
      <guid>https://forem.com/strapi/seo-friendly-pagination-solution-for-large-websites-1ago</guid>
      <description>&lt;p&gt;Pagination is one of the most overlooked SEO challenges for large websites.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fxthopmwnfkprmu9kzof3.png" class="article-body-image-wrapper"&gt;&lt;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%2Fxthopmwnfkprmu9kzof3.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Search engines struggle with deep crawlability&lt;/strong&gt;  — Traditional pagination structures often bury important content, making deep pages hard to reach.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Users get frustrated&lt;/strong&gt;  — Clicking through endless “Next” buttons or dealing with poorly designed pagination UI isn’t user-friendly.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We built an SEO-friendly pagination solution on our Strapi-powered blog at &lt;a href="https://deploi.ca/blog" rel="noopener noreferrer"&gt;Deploi.ca/blog&lt;/a&gt;, which has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4,100+ blog posts&lt;/li&gt;
&lt;li&gt;83 paginated listing pages&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This pagination system keeps deep content crawlable while providing a clean and intuitive user experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Smart, SEO-Optimized Pagination Solution
&lt;/h3&gt;

&lt;p&gt;Our pagination ensures that any listing page is reachable in just two clicks from the blog landing page while keeping the UI uncluttered.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;We use anchor pages and dynamic pagination updates instead of showing dozens of individual page links.&lt;/p&gt;

&lt;p&gt;When a user or search engine lands on a paginated page, they see a progressive pagination structure that adapts dynamically.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fadrbxi6n5jf46ajm151j.png" class="article-body-image-wrapper"&gt;&lt;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%2Fadrbxi6n5jf46ajm151j.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pagination Structure Example
&lt;/h3&gt;

&lt;p&gt;On the &lt;strong&gt;Deploi&lt;/strong&gt; blog, here’s the pagination you see on the first page:&lt;/p&gt;

&lt;p&gt;&lt;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%2F79o6z4pbbjhtv60wnf5f.png" class="article-body-image-wrapper"&gt;&lt;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%2F79o6z4pbbjhtv60wnf5f.png" width="715" height="275"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Users can navigate to the next page by clicking the second links. If we expand the ellipsis, here are the rendered links available to both users and search engines:&lt;/p&gt;

&lt;p&gt;&lt;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%2F6e8euexwiya2enoht5wm.png" class="article-body-image-wrapper"&gt;&lt;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%2F6e8euexwiya2enoht5wm.png" width="800" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Google has access to all the pagination links within the current range (1–9), as well as anchor pages, which we defined in increments of ten.&lt;/p&gt;

&lt;p&gt;In this example, let’s say Google follows anchor page 30, the pagination will dynamically update to look like this:&lt;/p&gt;

&lt;p&gt;&lt;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%2Fdgo0i565aijj95kp950k.png" class="article-body-image-wrapper"&gt;&lt;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%2Fdgo0i565aijj95kp950k.png" width="698" height="211"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see in the screenshot above, both users and Google have access to the previous page, the next page, the first page and the last page.&lt;/p&gt;

&lt;p&gt;But that’s not all, let’s reveal the first ellipsis by the left:&lt;/p&gt;

&lt;p&gt;&lt;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%2Fostgf497xjpk8ne2lfmz.png" class="article-body-image-wrapper"&gt;&lt;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%2Fostgf497xjpk8ne2lfmz.png" width="702" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now we can easily access all the previous anchor pages, which are pages 20 and 10.&lt;/p&gt;

&lt;p&gt;By expanding the second ellipsis, we see that Google can crawl all the pages within the current range (30–39) and also access all the remaining anchor pages (40, 50, 60, 70, and 80):&lt;/p&gt;

&lt;p&gt;&lt;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%2Fytfkf7tcls5jmdpp6aqh.png" class="article-body-image-wrapper"&gt;&lt;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%2Fytfkf7tcls5jmdpp6aqh.png" width="800" height="97"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we click on page 37 for example, which is in the current range, pagination will update accordingly:&lt;/p&gt;

&lt;p&gt;&lt;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%2F9tf4o0xuwwbphfkvcnpw.png" class="article-body-image-wrapper"&gt;&lt;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%2F9tf4o0xuwwbphfkvcnpw.png" width="578" height="158"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The shows that Google could reach the deepest listing page with only two link follows from the blog landng page and access any of the 4100+ blog posts with just three follows.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Code Behind It
&lt;/h3&gt;

&lt;p&gt;Our smart pagination system dynamically reveals relevant pages while keeping the UI intuitive. Let’s break down the key components of our React-based Pagination component.&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding the Props
&lt;/h3&gt;

&lt;p&gt;Our Pagination component uses the following props:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;pageCount - Total number of pages.&lt;/li&gt;
&lt;li&gt;gotoPage - Callback function to navigate to a different page.&lt;/li&gt;
&lt;li&gt;searchString - Optional search query parameter.&lt;/li&gt;
&lt;li&gt;startUrl - Base URL for page navigation.&lt;/li&gt;
&lt;li&gt;pageInde - Current active page.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Managing State
&lt;/h3&gt;

&lt;p&gt;We use React’s useState and useEffect hooks to handle page changes and dynamic visibility:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [activePage, setActivePage] = useState(pageIndex);
const [showLeftPages, setShowLeftPages] = useState(false);
const [showRightPages, setShowRightPages] = useState(false);

useEffect(() =&amp;gt; {
  setActivePage(pageIndex);
  setShowLeftPages(false);
  setShowRightPages(false);
}, [pageIndex]);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;activePage: Keeps track of the currently selected page.&lt;/li&gt;
&lt;li&gt;showLeftPages / showRightPages: Controls visibility of hidden anchor pages.&lt;/li&gt;
&lt;li&gt;useEffect resets visibility states when the page index updates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Generating Page Numbers
&lt;/h3&gt;

&lt;p&gt;To create an SEO-friendly pagination structure, we generate page numbers dynamically:&lt;/p&gt;

&lt;p&gt;This ensures:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The first and last pages are always visible.&lt;/li&gt;
&lt;li&gt;The current page and its neighbors (previous/next) are included.&lt;/li&gt;
&lt;li&gt;Anchor pages at every 10th interval are displayed.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Handling Visibility
&lt;/h3&gt;

&lt;p&gt;To avoid clutter, we only show pages based on specific conditions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const isVisible = (page) =&amp;gt; {
  if (page === 1 || page === pageCount) return true;
  if (page === activePage - 1 || page === activePage || page === activePage + 1) return true;
  if (showLeftPages &amp;amp;&amp;amp; page &amp;lt; activePage) return true;
  if (showRightPages &amp;amp;&amp;amp; page &amp;gt; activePage) return true;
  return false;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;First and last pages are always visible.&lt;/li&gt;
&lt;li&gt;Previous, current, and next pages are always included.&lt;/li&gt;
&lt;li&gt;Clicking the left/right ellipsis reveals the hidden anchor and current range pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Handling Page Clicks
&lt;/h3&gt;

&lt;p&gt;When a user selects a page, we update the state and trigger the gotoPage function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handlePageChange = (page) =&amp;gt; {
  if (page &amp;gt;= 1 &amp;amp;&amp;amp; page &amp;lt;= pageCount) {
    setShowLeftPages(false);
    setShowRightPages(false);
    gotoPage &amp;amp;&amp;amp; gotoPage(page);
  }
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For ellipsis clicks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleLeftEllipsisClick = () =&amp;gt; {
  setShowLeftPages(true);
  setShowRightPages(false);
};

const handleRightEllipsisClick = () =&amp;gt; {
  setShowRightPages(true);
  setShowLeftPages(false);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Clicking the left ellipsis expands previous anchor pages.&lt;/li&gt;
&lt;li&gt;Clicking the right ellipsis expands future anchor pages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Rendering the Pagination UI
&lt;/h3&gt;

&lt;p&gt;Each page number is displayed dynamically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const renderPageNumbers = () =&amp;gt; {
  const pages = generatePageNumbers();
  let lastRenderedPage = 0;

  return (
    &amp;lt;ul className="flex items-center justify-center gap-2 flex-wrap"&amp;gt;
      {pages.map((page, index) =&amp;gt; {
        const shouldShowLeftEllipsis =
          !showLeftPages &amp;amp;&amp;amp;
          ((page &amp;gt; 2 &amp;amp;&amp;amp; page &amp;lt;= activePage &amp;amp;&amp;amp; lastRenderedPage === 1) ||
            (activePage &amp;gt;= 3 &amp;amp;&amp;amp; activePage &amp;lt;= 9 &amp;amp;&amp;amp; page === 2));

        const shouldShowRightEllipsis =
          !showRightPages &amp;amp;&amp;amp;
          page &amp;lt; pageCount &amp;amp;&amp;amp;
          page &amp;gt;= activePage &amp;amp;&amp;amp;
          pages[index + 1] === pageCount;

        const isPageVisible = isVisible(page);
        lastRenderedPage = page;

        return (
          &amp;lt;React.Fragment key={page}&amp;gt;
            {shouldShowLeftEllipsis &amp;amp;&amp;amp; (
              &amp;lt;li
                onClick={handleLeftEllipsisClick}
                className="cursor-pointer text-primary-100 w-[40px] h-[40px] flex items-center justify-center hover:bg-primary-50 transition-colors rounded-full border border-primary-100"
              &amp;gt;
                ...
              &amp;lt;/li&amp;gt;
            )}
            &amp;lt;li
              className={`${!isPageVisible ? "hidden" : ""} cursor-pointer border border-primary-100 text-base font-semibold text-primary-100 rounded-full w-[40px] h-[40px] flex items-center justify-center hover:bg-primary-50 transition-colors ${page === activePage ? "bg-primary-100 text-white" : ""}`}
            &amp;gt;
              &amp;lt;a
                href={
                  searchString
                    ? `${startUrl}?p=${page}&amp;amp;q=${searchString}`
                    : `${startUrl}?p=${page}`
                }
                className="w-full h-full flex items-center justify-center"
              &amp;gt;
                {page &amp;lt; 10 ? `0${page}` : page}
              &amp;lt;/a&amp;gt;
            &amp;lt;/li&amp;gt;
            {shouldShowRightEllipsis &amp;amp;&amp;amp; (
              &amp;lt;li
                onClick={handleRightEllipsisClick}
                className="cursor-pointer text-primary-100 w-[40px] h-[40px] flex items-center justify-center hover:bg-primary-50 transition-colors rounded-full border border-primary-100"
              &amp;gt;
                ...
              &amp;lt;/li&amp;gt;
            )}
          &amp;lt;/React.Fragment&amp;gt;
        );
      })}
    &amp;lt;/ul&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;If needed, the left ellipsis (...) is displayed before hidden pages.&lt;/li&gt;
&lt;li&gt;If needed, the right ellipsis (...) is displayed after the current range.&lt;/li&gt;
&lt;li&gt;Page links dynamically update based on visibility logic.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Wrapping Everything Together
&lt;/h3&gt;

&lt;p&gt;Finally, the component renders the pagination UI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
  &amp;lt;div className="flex flex-col md:flex-row justify-center items-center"&amp;gt;
    {renderPageNumbers()}
  &amp;lt;/div&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ensures our pagination works across different screen sizes.&lt;/p&gt;

&lt;p&gt;By structuring pagination this way, we ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Efficient crawling for search engines (deep content remains discoverable).&lt;/li&gt;
&lt;li&gt;User-friendly navigation is retained by hiding crawler-focused links behind ellipsis.&lt;/li&gt;
&lt;li&gt;Scalability for any large website (whether a blog, eCommerce store, or content-heavy platform).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach solves pagination SEO issues while maintaining a great user experience.&lt;/p&gt;

&lt;p&gt;Want to implement this on your site? Get in touch with us at &lt;a href="https://deploi.ca" rel="noopener noreferrer"&gt;Deploi.ca&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://strapi.io/blog/seo-friendly-pagination-solution-for-large-websites" rel="noopener noreferrer"&gt;&lt;em&gt;https://strapi.io&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>nextjs</category>
      <category>webdev</category>
      <category>strapi</category>
      <category>react</category>
    </item>
    <item>
      <title>Epic Next JS 15 Tutorial Part 8: Search and Pagination in Next.js</title>
      <dc:creator>Solomon Eseme</dc:creator>
      <pubDate>Mon, 28 Apr 2025 17:54:11 +0000</pubDate>
      <link>https://forem.com/strapi/epic-next-js-15-tutorial-part-8-search-and-pagination-in-nextjs-5275</link>
      <guid>https://forem.com/strapi/epic-next-js-15-tutorial-part-8-search-and-pagination-in-nextjs-5275</guid>
      <description>&lt;p&gt;&lt;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%2Fm7q1cufrra01eu7h92z0.png" class="article-body-image-wrapper"&gt;&lt;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%2Fm7q1cufrra01eu7h92z0.png" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are making amazing progress. We are now in the final stretch. In this section, we will look at Search and Pagination.&lt;/p&gt;

&lt;p&gt;&lt;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%2Flsck26aj5rh72gu9addx.png" class="article-body-image-wrapper"&gt;&lt;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%2Flsck26aj5rh72gu9addx.png" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  How To Handle Search In Next.js
&lt;/h3&gt;

&lt;p&gt;Let’s jump in and look at how to implement search with Next.js and Strapi CMS.&lt;/p&gt;

&lt;p&gt;First, create a new file inside our src/components/custom folder called search.tsx and add the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import { useDebouncedCallback } from "use-debounce";
import { Input } from "@/components/ui/input";

export function Search() {
  const searchParams = useSearchParams();
  const { replace } = useRouter();
  const pathname = usePathname();

  const handleSearch = useDebouncedCallback((term: string) =&amp;gt; {
    console.log(`Searching... ${term}`);
    const params = new URLSearchParams(searchParams);
    params.set("page", "1");

    if (term) {
      params.set("query", term);
    } else {
      params.delete("query");
    }

    replace(`${pathname}?${params.toString()}`);
  }, 300);

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;Input
        type="text"
        placeholder="Search"
        onChange={(e) =&amp;gt; handleSearch(e.target.value)}
        defaultValue={searchParams.get("query")?.toString()}
      /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The secret to understanding how our &lt;strong&gt;Search&lt;/strong&gt; component works is to be familiar with the following hooks from Next.js.&lt;/p&gt;

&lt;p&gt;We use it in our code to get our current parameters from our url.&lt;/p&gt;

&lt;p&gt;Then, we use the new URLSearchParams to update our search parameters. You can learn more about it &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://nextjs.org/docs/pages/api-reference/functions/use-router" rel="noopener noreferrer"&gt;docs reference&lt;/a&gt; : Allows us to access the router object inside any function component in your app. We will use the replace method to prevent adding a new URL entry into the history stack.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;usePathname&lt;/strong&gt; &lt;a href="https://nextjs.org/docs/app/api-reference/functions/use-pathname" rel="noopener noreferrer"&gt;docs reference&lt;/a&gt;: This is a Client Component hook that lets you read the current URL's pathname. We use it to find our current path before concatenating our new search parameters.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;useDebouncedCallback&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/use-debounce" rel="noopener noreferrer"&gt;npm reference&lt;/a&gt;: Used to prevent making an api call on every keystroke when using our Search component.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Install the use-debounce package from &lt;a href="https://www.npmjs.com/package/use-debounce" rel="noopener noreferrer"&gt;npm&lt;/a&gt; with the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add use-debounce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s look at the flow of our Search component’s work by looking at the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
  &amp;lt;div&amp;gt;
    &amp;lt;Input
      type="text"
      placeholder="Search"
      onChange={(e) =&amp;gt; handleSearch(e.target.value)}
      defaultValue={searchParams.get("query")?.toString()}
    /&amp;gt;
  &amp;lt;/div&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are using the defaultValue prop to set the current search parameters from our URL.&lt;/p&gt;

&lt;p&gt;When the onChange fires, we pass the value to our handleSearch function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleSearch = useDebouncedCallback((term: string) =&amp;gt; {
  console.log(`Searching... ${term}`);
  const params = new URLSearchParams(searchParams);
  params.set("page", "1");

  if (term) {
    params.set("query", term);
  } else {
    params.delete("query");
  }

  replace(`${pathname}?${params.toString()}`);
}, 300);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the handleSearch function, we use replace to set our new search parameters in our URL.&lt;/p&gt;

&lt;p&gt;So whenever we type the query in our input field, it will update our URL.&lt;/p&gt;

&lt;p&gt;Let’s now add our Search component to our code.&lt;/p&gt;

&lt;p&gt;Navigate to the src/app/dashboard/summaries/page.tsx file and update it with the following code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Link from "next/link";
import { getSummaries } from "@/data/loaders";
import ReactMarkdown from "react-markdown";

import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Search } from "@/components/custom/search";

interface LinkCardProps {
  documentId: string;
  title: string;
  summary: string;
}

function LinkCard({ documentId, title, summary }: Readonly&amp;lt;LinkCardProps&amp;gt;) {
  return (
    &amp;lt;Link href={`/dashboard/summaries/${documentId}`}&amp;gt;
      &amp;lt;Card className="relative"&amp;gt;
        &amp;lt;CardHeader&amp;gt;
          &amp;lt;CardTitle className="leading-8 text-pink-500"&amp;gt;
            {title || "Video Summary"}
          &amp;lt;/CardTitle&amp;gt;
        &amp;lt;/CardHeader&amp;gt;
        &amp;lt;CardContent&amp;gt;
          &amp;lt;ReactMarkdown
            className="card-markdown prose prose-sm max-w-none
              prose-headings:text-gray-900 prose-headings:font-semibold
              prose-p:text-gray-600 prose-p:leading-relaxed
              prose-a:text-pink-500 prose-a:no-underline hover:prose-a:underline
              prose-strong:text-gray-900 prose-strong:font-semibold
              prose-ul:list-disc prose-ul:pl-4
              prose-ol:list-decimal prose-ol:pl-4"
          &amp;gt;
            {summary.slice(0, 164) + " [read more]"}
          &amp;lt;/ReactMarkdown&amp;gt;
        &amp;lt;/CardContent&amp;gt;
      &amp;lt;/Card&amp;gt;
    &amp;lt;/Link&amp;gt;
  );
}

interface SearchParamsProps {
  searchParams?: {
    query?: string;
  };
}

export default async function SummariesRoute({
  searchParams,
}: SearchParamsProps) {
  const search = await searchParams;
  const query = search?.query ?? "";
  console.log(query);
  const { data } = await getSummaries();

  if (!data) return null;
  return (
    &amp;lt;div className="grid grid-cols-1 gap-4 p-4"&amp;gt;
      &amp;lt;Search /&amp;gt;
      &amp;lt;div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4"&amp;gt;
        {data.map((item: LinkCardProps) =&amp;gt; (
          &amp;lt;LinkCard key={item.documentId} {...item} /&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;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%2Fd8cbz8tclt3cqp1n2hrl.gif" class="article-body-image-wrapper"&gt;&lt;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%2Fd8cbz8tclt3cqp1n2hrl.gif" width="1510" height="382"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Excellent. Now that our Search component shows up, let's move on to the second part. We'll pass our query search through our getSummaries function and update it accordingly to allow us to search our queries.&lt;/p&gt;

&lt;p&gt;To make the search work, we will rely on the following parameters.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;sorting&lt;/strong&gt; : we will sort all of our summaries in descending order, ensuring that the newest summary appears first.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;filters&lt;/strong&gt; : The filters we will use $or operator to combine our search conditions. This means the search will return summaries based on the fields we will filter using $containsi, which will ignore case sensitivity.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let’s look inside our src/data/loaders.ts file and update the following code inside our getSummaries function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function getSummaries() {
  const url = new URL("/api/summaries", baseUrl);
  return fetchData(url.href);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here are the changes we are going to make.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function getSummaries(queryString: string) {
  const query = qs.stringify({
    sort: ["createdAt:desc"],
    filters: {
      $or: [
        { title: { $containsi: queryString } },
        { summary: { $containsi: queryString } },
      ],
    },
  });
  const url = new URL("/api/summaries", baseUrl);
  url.search = query;
  return fetchData(url.href);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will create a query to filter our summaries on the title and summary.&lt;/p&gt;

&lt;p&gt;Now, we have one more step before testing our search. Let’s navigate back to the src/app/dashboard/summaries folder and make the following changes inside our page.tsx file.&lt;/p&gt;

&lt;p&gt;We cannot pass and utilize our query params since we just updated our getSummaries function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { data } = await getSummaries(query);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s see if our search is working.&lt;/p&gt;

&lt;p&gt;&lt;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%2Fuk1inp7fog3a9wmyxr9t.png" class="article-body-image-wrapper"&gt;&lt;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%2Fuk1inp7fog3a9wmyxr9t.png" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great. Now that our search is working, we can simply move forward with our pagination.&lt;/p&gt;

&lt;h3&gt;
  
  
  How To Handle Pagination In Your Next.js Project
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Pagination Basics
&lt;/h3&gt;

&lt;p&gt;Pagination involves dividing content into separate pages and providing users with controls to navigate to the first, last, previous, following, or specific page.&lt;/p&gt;

&lt;p&gt;This method improves performance by reducing the amount of data loaded simultaneously. It makes it easier for users to find specific information by browsing through a smaller subset of data.&lt;/p&gt;

&lt;p&gt;Let’s implement our pagination, but first, let’s walk through the code example below, which we will use for our &lt;strong&gt;PaginationComponent&lt;/strong&gt; inside of our Next.js project.&lt;/p&gt;

&lt;p&gt;It is based on the Shadcn UI component that you can take a look at &lt;a href="https://ui.shadcn.com/docs/components/pagination" rel="noopener noreferrer"&gt;here&lt;/a&gt;;&lt;/p&gt;

&lt;p&gt;So, run the following command to get all the necessary dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx shadcn@latest add pagination
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And add the following code to your components/custom folder file called pagination-component.tsx.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"use client";
import { FC } from "react";
import { usePathname, useSearchParams, useRouter } from "next/navigation";

import {
  Pagination,
  PaginationContent,
  PaginationItem,
} from "@/components/ui/pagination";

import { Button } from "@/components/ui/button";

interface PaginationProps {
  pageCount: number;
}

interface PaginationArrowProps {
  direction: "left" | "right";
  href: string;
  isDisabled: boolean;
}

const PaginationArrow: FC&amp;lt;PaginationArrowProps&amp;gt; = ({
  direction,
  href,
  isDisabled,
}) =&amp;gt; {
  const router = useRouter();
  const isLeft = direction === "left";
  const disabledClassName = isDisabled ? "opacity-50 cursor-not-allowed" : "";

  return (
    &amp;lt;Button
      onClick={() =&amp;gt; router.push(href)}
      className={`bg-gray-100 text-gray-500 hover:bg-gray-200 ${disabledClassName}`}
      aria-disabled={isDisabled}
      disabled={isDisabled}
    &amp;gt;
      {isLeft ? "«" : "»"}
    &amp;lt;/Button&amp;gt;
  );
};

export function PaginationComponent({ pageCount }: Readonly&amp;lt;PaginationProps&amp;gt;) {
  const pathname = usePathname();
  const searchParams = useSearchParams();
  const currentPage = Number(searchParams.get("page")) || 1;

  const createPageURL = (pageNumber: number | string) =&amp;gt; {
    const params = new URLSearchParams(searchParams);
    params.set("page", pageNumber.toString());
    return `${pathname}?${params.toString()}`;
  };

  return (
    &amp;lt;Pagination&amp;gt;
      &amp;lt;PaginationContent&amp;gt;
        &amp;lt;PaginationItem&amp;gt;
          &amp;lt;PaginationArrow
            direction="left"
            href={createPageURL(currentPage - 1)}
            isDisabled={currentPage &amp;lt;= 1}
          /&amp;gt;
        &amp;lt;/PaginationItem&amp;gt;
        &amp;lt;PaginationItem&amp;gt;
          &amp;lt;span className="p-2 font-semibold text-gray-500"&amp;gt;
            Page {currentPage}
          &amp;lt;/span&amp;gt;
        &amp;lt;/PaginationItem&amp;gt;
        &amp;lt;PaginationItem&amp;gt;
          &amp;lt;PaginationArrow
            direction="right"
            href={createPageURL(currentPage + 1)}
            isDisabled={currentPage &amp;gt;= pageCount}
          /&amp;gt;
        &amp;lt;/PaginationItem&amp;gt;
      &amp;lt;/PaginationContent&amp;gt;
    &amp;lt;/Pagination&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, we are using our familiar hooks from before to make this work, usePathname, searchParams, and useRouter in a similar way as we did before.&lt;/p&gt;

&lt;p&gt;We are receiving pageCount via props to see our available pages. Inside the PaginationArrow component, we use useRouter to programmatically update our URL via the push method on click.&lt;/p&gt;

&lt;p&gt;Let’s add this component to our project. In our components/custom folder, create a PaginationComponent.tsx file and paste it into the above code.&lt;/p&gt;

&lt;p&gt;Now that we have our component, let’s navigate to src/app/dashboard/summaries/page.tsx and import it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { PaginationComponent } from "@/components/custom/pagination-component";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now update our SearchParamsProps interface to the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;interface SearchParamsProps {
  searchParams?: {
    page?: string;
    query?: string;
  };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s create a currentPage variable to store the current page we get from our URL parameters.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const currentPage = Number(searchParams?.page) || 1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we can pass our currentPage to our getSummaries function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { data } = await getSummaries(query, currentPage);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let’s go back to our loaders. tsx file and update the getSummaries with the following code to utilize our pagination.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export async function getSummaries(queryString: string, currentPage: number) {
  const PAGE_SIZE = 4;

  const query = qs.stringify({
    sort: ["createdAt:desc"],
    filters: {
      $or: [
        { title: { $containsi: queryString } },
        { summary: { $containsi: queryString } },
      ],
    },
    pagination: {
      pageSize: PAGE_SIZE,
      page: currentPage,
    },
  });
  const url = new URL("/api/summaries", baseUrl);
  url.search = query;
  return fetchData(url.href);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we use Strapi’s pagination fields and pass pageSize and page fields. You can learn more about Strapi's pagination &lt;a href="https://docs.strapi.io/dev-docs/api/rest/sort-pagination" rel="noopener noreferrer"&gt;here&lt;/a&gt;;&lt;/p&gt;

&lt;p&gt;Now back in our src/app/dashboard/summaries/page.tsx, let's make a few more minor changes before hooking everything up.&lt;/p&gt;

&lt;p&gt;If we look at our getSummaries call, we have access to another field that Strapi is returning called meta. Let's make sure we are getting it from our response with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const { data, meta } = await getSummaries(query, currentPage);
console.log(meta);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will see the following data if we console log our meta field.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ pagination: { page: 1, pageSize: 4, pageCount: 1, total: 4 } }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that we have our pageCount property. We will use it to tell our &lt;strong&gt;PaginationComponent&lt;/strong&gt; the number of pages we have available.&lt;/p&gt;

&lt;p&gt;So, let’s extract it from our meta data with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  const pageCount = meta?.pagination?.pageCount;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And finally, let’s use our &lt;strong&gt;PaginationComponent&lt;/strong&gt; with the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;PaginationComponent pageCount={pageCount} /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The completed code should look like the following.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import Link from "next/link";
import { getSummaries } from "@/data/loaders";
import ReactMarkdown from "react-markdown";

import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import { Search } from "@/components/custom/search";
import { PaginationComponent } from "@/components/custom/pagination-component";

interface LinkCardProps {
  documentId: string;
  title: string;
  summary: string;
}

function LinkCard({ documentId, title, summary }: Readonly&amp;lt;LinkCardProps&amp;gt;) {
  return (
    &amp;lt;Link href={`/dashboard/summaries/${documentId}`}&amp;gt;
      &amp;lt;Card className="relative"&amp;gt;
        &amp;lt;CardHeader&amp;gt;
          &amp;lt;CardTitle className="leading-8 text-pink-500"&amp;gt;
            {title || "Video Summary"}
          &amp;lt;/CardTitle&amp;gt;
        &amp;lt;/CardHeader&amp;gt;
        &amp;lt;CardContent&amp;gt;
          &amp;lt;ReactMarkdown 
            className="card-markdown prose prose-sm max-w-none
              prose-headings:text-gray-900 prose-headings:font-semibold
              prose-p:text-gray-600 prose-p:leading-relaxed
              prose-a:text-pink-500 prose-a:no-underline hover:prose-a:underline
              prose-strong:text-gray-900 prose-strong:font-semibold
              prose-ul:list-disc prose-ul:pl-4
              prose-ol:list-decimal prose-ol:pl-4"
          &amp;gt;
            {summary.slice(0, 164) + " [read more]"}
          &amp;lt;/ReactMarkdown&amp;gt;
        &amp;lt;/CardContent&amp;gt;
      &amp;lt;/Card&amp;gt;
    &amp;lt;/Link&amp;gt;
  );
}

interface SearchParamsProps {
  searchParams?: {
    page?: string;
    query?: string;
  };
}

export default async function SummariesRoute({ searchParams }: SearchParamsProps) {
  const search = await searchParams;
  const query = search?.query ?? ""; 
  const currentPage = Number(search?.page) || 1;

  const { data, meta } = await getSummaries(query, currentPage);
  const pageCount = meta?.pagination?.pageCount;

  console.log(meta);  

  if (!data) return null;
  return (
    &amp;lt;div className="grid grid-cols-1 gap-4 p-4"&amp;gt;
      &amp;lt;Search /&amp;gt;
      &amp;lt;div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4"&amp;gt;
        {data.map((item: LinkCardProps) =&amp;gt; (
          &amp;lt;LinkCard key={item.documentId} {...item} /&amp;gt;
        ))}
      &amp;lt;/div&amp;gt;
      &amp;lt;PaginationComponent pageCount={pageCount} /&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, the moment of truth: Let’s see if it works. Make sure you add more summaries since our page size is currently set to 4 items. You need to have at least 5 items.&lt;/p&gt;

&lt;p&gt;&lt;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%2Frnqclq3ozak5mwc7pxht.gif" class="article-body-image-wrapper"&gt;&lt;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%2Frnqclq3ozak5mwc7pxht.gif" width="800" height="453"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Excellent, it is working.&lt;/p&gt;

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

&lt;p&gt;This Next.js with Strapi CMS tutorial covered how to implement search and pagination functionalities. Hope you are enjoying this tutorial.&lt;/p&gt;

&lt;p&gt;We are almost done. We have two more sections to go, including deploying our project to Strapi Cloud and Vercel.&lt;/p&gt;

&lt;p&gt;See you in the next post.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://strapi.io/blog/epic-next-js-14-tutorial-part-8-search-and-pagination-in-next-js" rel="noopener noreferrer"&gt;&lt;em&gt;https://strapi.io&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;




</description>
      <category>webdev</category>
      <category>strapi</category>
      <category>coding</category>
      <category>nextjs</category>
    </item>
  </channel>
</rss>
