Skip to main content
FomiVIP
Tech Sharing

Rewriting a Legacy PHP API in Node.js: Keeping 3 Old Parameters Alive

The port took two days; not breaking callers took weeks. Half a year of Nginx logs revealed three kinds of legacy callers — a cron job, a misspelled dashboard param, and an Excel Web Query macro. We kept a thin compatibility layer, never touched response shapes, and gray-released over three weeks.

January 18, 2024Node.jsLegacy MigrationAPI Compatibility

An old reporting API, written in PHP 5.6, had run for seven years. Migrating it to Node.js, the code itself translated in two or three days. What really took time was not breaking anyone.

First, Find Who's Calling

Nobody could say for sure who was using this API. The docs had stopped at 2019, listing 2 callers — clearly incomplete.

The method was crude: pull six months of Nginx access logs, filter by path, and break down the query strings into stats. We found 3 kinds of requests carrying old parameters:

  • An internal cron job still passing old enums like type=1.
  • A client-built dashboard with a misspelled parameter name that had always worked, thanks to fault tolerance on the PHP side.
  • The most surprising: an Excel macro on an office PC pulling data via Web Query, its User-Agent that familiar Office string.

Had we missed the third one, that report would have gone blank on day two after launch — and nobody would ever have thought to check a macro.

How the Compatibility Layer Was Kept

The new API's parameters were redesigned, but we kept an adapter at the outer layer: old parameters are still accepted and mapped to the new fields internally; legacy enums like type=1 translate to the new ones; the misspelled parameter name also stays, marked deprecated.

The response JSON's field names and structure didn't change at all. Changing the response is far more dangerous than changing parameters — downstream code tends to index directly into it.

We also log one line per request: raw parameters, which caller type we identified, and whether the compatibility branch fired. Over two months we worked down that list, contacting owners one by one and migrating the cron job and dashboard to the new parameters. The Excel macro stayed put — the client said that PC has two more years of life in it.

The Gray Release

Both versions ran in parallel for 3 weeks, with Nginx splitting traffic by cookie — the same playbook as our earlier gray releases. The old API stayed up 7 more days before shutting down, and only after logs confirmed no more incoming requests.

One small trap: Node.js handles numeric precision the JavaScript way by default. A 17-digit order number in the report came back to Excel with trailing zeros. We caught it and switched to returning it as a string before things matched again. PHP-era code never hits this — it came with the language switch.

Where It Stands

The compatibility layer is still there — a switch statement under 30 lines, with a comment: "Don't remove; Excel still uses this." We'll deal with it when that PC retires.

In a migration like this, writing the code is the shortest part.

Consulting · Free initial chat

Need advice for your scenario?

Tell us your business context and current systems, and we'll give an actionable approach.

Contact us

Mon–Fri 9:00–18:00 · We respond on business days within one business day.

WeChat (Business Only)
WeChat (Business Only)二维码

Scan and add our WeChat for consulting

Or fill out the requirements form