Decimal numbers with trailing zeros and handling raw body data in Node.js
Alan Norman
Posted on September 3, 2024
By Alan Norman
So, a few years back, I ran into this annoying issue with decimal numbers that had trailing zeros in Node.js. It was one of those sneaky problems that ate up almost an entire day, and I'm sharing my story in the hopes that it saves you some headache if you ever stumble upon the same tiny but frustrating problem.
The Problem: Decimal Numbers with .00 Losing Their Trailing Zeros
During one of my projects, where I was rolling as the Solution Lead, our team was working on a service that hooked up with a bunch of financial platforms. These platforms kept hitting us with JSON payloads via POST requests, and our Node.js app, running on the Express framework, was on duty to handle them. We used app.use(express.json())
to parse the incoming JSON data.
Everything was smooth sailing until one of our partners started sending JSON with an “amount” key that had those pesky trailing zeros, like “amount”: “10.00”. The problem? JavaScript doesn’t give a hoot about the difference between 10.00 and 10 when converting strings to numbers. This caused a big mess because we needed to generate a digital signature from the raw request body. If the signature was made from “amount”: “10” instead of “amount”: “10.00”, boom—mismatch city.
The Challenge: Keeping the Original JSON Format Intact
Now, app.use(express.json())
was doing its job too well, automatically parsing the JSON and stripping away those precious zeros, leaving us with no way to grab the raw JSON string. We couldn’t just rip out app.use(express.json())
because that would mean rewriting a ton of code and breaking all the SOLID principles we were holding dear.
Our quick and dirty fix? We started tweaking the amounts by adding small values, turning 10.00 into 10.01. It gave us some breathing room to figure things out, but come on, this was never gonna fly long-term—especially in a financial setup where accuracy is everything.
The Fix: Using the verify Option in express.json()
After digging around a bit, I found out the fix was way simpler than I expected. Turns out, Express has this neat verify
option in the express.json()
method that lets you grab the raw request body before it gets all parsed into JSON.
Here’s how you can make it work:
app.use(express.json({
verify: (req, _, buf) => req.rawBody = Buffer.from(buf).toString()
}));
The verify
function kicks in before the body is turned into JSON. This way, you can stash the raw body as a string, making sure that “amount”: “10.00” stays just the way it was. Then, you can grab both the parsed JSON and the raw string in your controllers:
const { body, rawBody } = req;
// body - JSON-parsed output
// rawBody - Original raw string received before parsing
Heads Up: Be Careful When Messing with the req Object
Now, I gotta say, messing with the req
object isn’t exactly best practice, but hey, sometimes you gotta do what you gotta do to fit your architecture. The main thing to remember is that you can keep both the raw and parsed versions of the JSON body in one spot.
Looking back, the fix was right there, but under pressure, even seasoned devs can miss the easy stuff. Hopefully, this helps anyone else facing the same kind of hassle. Remember, knowing how your tools really work under the hood can often turn complex problems into simple fixes.
Happy coding, folks!
Posted on September 3, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.