The frontend did not have to read f_title
Impact
The frontend never sees f_title
In 2024 I had the chance to take part in the initial build of a classifieds marketplace. The website was new. The APIs were not. On the server we parsed the JSON with Zod so the frontend read `title`, not `f_title`.
In 2024 I had the chance to take part in the initial build of a classifieds marketplace. The website was new. The APIs were not. The JSON arrived with names nobody would want to read in a component. A dump looked more or less like this:
{
"id": "4412",
"f_title": "Bicicleta de montaña",
"f_descr": "Poco uso",
"f_price": "12990.5",
"usdprice": 140,
"userid": "8821",
"f_contact": "Ana",
"categoryname": "Deportes"
}It was not a naming mess. It was the contract. f_ prefixes, glued names (userid, categoryname), the price sometimes text and sometimes a number. If we copied that into the screen code, the listing was going to talk like that for the rest of the project.
If that reaches the frontend, it is already your model
TypeScript does not complain if you type any or copy an interface off what arrived. Next day ad.f_title is already on three screens. The day they change f_title to title, it is not "the integration" that breaks. You get a blank, and you find out that afternoon on Slack.
We were not going to rewrite those APIs. We were not going to inherit them either. If the frontend kept the raw JSON, every new screen copied the same keys. The problem stopped being theirs. It became ours.
We changed it on the server, before the screen
On the server we built Zod schemas. The z.object listed the ugly keys. The transform returned what we actually wanted to use: title, description, price, user. The frontend imported Ad. Not f_title.
The schema was not glued to the fetch. Types in one package, HTTP in another. Both on the server. The endpoint parsed and returned the internal type. If the listing did not match, .parse() threw. The frontend did not get a half object.
If the API added a property, it did not show up on Ad until someone put it in the schema. That cleaned up the screens. It did not clean up everything.
What still leaked
Filters and sort still talked like the listing: f_price, f_added in the URL. The frontend read title. The address bar did not. We said "the API asks for it that way" and the ugly name stayed there.
If you cut nothing, it is worse. A hook asks for the raw object "just in case". Three screens read f_title. The blank does not point at the JSON from outside. It points at a component.
Close
The frontend did not need to know f_title existed. If you want the steps today, stricter than what we did there, they are in The third-party API is not your model. We did not have that note then. We had the schema on the server and the screens reading Ad.