LogoTRUONG PHAM
Home
Projects
Blogs
YouTube
Contact

Newsletter

Stay updated with technical artifacts and engineering insights.

LogoTRUONG PHAM

Building scalable software and sharing insights on technology & life.

Sitemap

  • Home
  • Projects
  • Blogs
  • YouTube
  • Contact

Connect

  • GitHub
  • LinkedIn
  • Email
  • YouTube

© 2024 TRUONG PHAM. © All rights reserved.

Privacy PolicyTerms of Service
Back
Blog #42: When the Backend Changes the Schema and the Fragility of the Frontend
50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

Blog #42: When the Backend Changes the Schema and the Fragility of the Frontend

The story of a project collapsing just because the Backend renamed a field and a lesson on the Data Mapping layer.

TP
Truong PhamSoftware Engineer
PublishedAugust 10, 2024

To my past self,

Do you still remember the shock when the Dashboard suddenly failed to display the revenue chart? The Backend simply changed a field name from total_price to totalPrice for "naming standards," but they forgot to tell you. And just like that, all your calculation logic on the Frontend was paralyzed.

At that time, you frantically searched for the keyword total_price throughout the entire project to fix it by hand. You felt like a slave to the API.

The Problem: Over-dependence

Simply put, you were letting the Frontend "speak" directly in the Backend's language. When the Backend changed its voice, the Frontend immediately went deaf. You were using exactly what the API returned to display on the interface, without any filter in between.

Current Perspective: The Vital Buffer Layer

Now, I never directly use API results in display components. A common junior mistake is mapping API variables directly into a component's State.

// How you used to do it (dangerous)
const [orders, setOrders] = useState([]);
useEffect(() => {
  fetch('/api/orders').then(res => setOrders(res.data));
}, []);

// In JSX
return orders.map(order => <span>{order.total_price}</span>);

The problem is that the keyword total_price now appears in 20 different places in the project. When the Backend changes the name, you have to fix it in 20 places. That is a loose and fragile design.

Sustainable Solution: DTO and Data Mapping

In sustainable systems, we need a layer called a Mapper or Adapter. As soon as data arrives at the Frontend, we convert it into the format the Frontend desires (DTO - Data Transfer Object).

Comparison:

  • Quick fix: Fix code wherever there's an error. Fast but leaves a high risk of missing bugs.
  • Sustainable way: Create a data mapping function right at the service layer. If the Backend renames a field, I only need to fix a single line in this mapping function. The entire UI below keeps its logic because they use the variable names I've defined.
// Sustainable way: Separating data logic
const orderMapper = (apiData) => ({
  id: apiData.id,
  totalPrice: apiData.total_price || apiData.totalPrice || 0, // Handles both old and new
  customerName: apiData.customer_info?.name
});

const orders = rawData.map(orderMapper);

Practical Lesson

The Frontend should have sovereignty over its own data structure. Don't let a change in another system (Backend) break your logical thinking. Taking an extra 5 minutes to write a mapping function will save you from hours of Find & Replace later.

Build a shield to protect your code.


Notes on the necessary independence of data.

Series • Part 42 of 50

50 FRONTEND LESSONS – HARD-EARNED EXPERIENCES

NextBlog #43: CORS Isn't Always the Backend's Fault
Blog #41: The 2 AM Panic and Infinite Question Marks
37Blog #37: The Reusability Trap – When a 'multi-purpose' Component becomes a burden38Blog #38: Micro-frontend Reality Check – When theoretical glory meets harsh reality39Blog #39: The 'Will Fix Later' Promise and the Compound Interest of Technical Debt40Blog #40: Don't try to be smart – Write code for humans, not for machines41Blog #41: The 2 AM Panic and Infinite Question Marks42Blog #42: When the Backend Changes the Schema and the Fragility of the FrontendReading43Blog #43: CORS Isn't Always the Backend's Fault44Blog #44: CI/CD and Environment Variables that 'Disappear' Without a Trace45Blog #45: The Brutal Difference Between Staging and Production46Blog #46: Feature Flag – The 'Lifebuoy' for Risky Releases47Blog #47: Long-term Tab Crash – What happens when Users never close their Tabs?
TP

Written by Truong Pham

Software Engineer passionate about building high-performance systems and meaningful experiences.

Read more articles