DEV Community

Jackson Ly
Jackson Ly

Posted on

Test the second access path before you call a metric unreadable

I keep a list of surfaces whose numbers I could not read, with a short reason written next to each one. Discourse gives you nothing per post. The comments API has no reaction field. Once a line like that is written down it stops looking like a hypothesis, and nothing in my process ever reopened one.

This week I re-probed four of them and three turned out to be readable.

Discourse was the embarrassing one, because the data is sitting behind a public URL:

GET https://<instance>/t/<topic_id>.json
Enter fullscreen mode Exit fullscreen mode

That gives you post_stream.posts[], and every entry carries reads, score, and an actions_summary array where id 2 is the like count. No key, no session. Two posts I had written off came back with 52 and 34 reads against 212 topic views, which is not nothing for a niche forum.

A Vanilla forum was next, and there my note was half right. The rendered comment page really does have no count element on it, so the thing I checked behaved exactly as I recorded. What I never tried was GET /api/v2/comments/<id>, which answers 200 without any auth and returns a structured object.

dev.to caught me the same way, in reverse. Its comments API hands back a comment object with no reaction count, which I verified and wrote down accurately. The rendered comment permalink prints the number into the markup:

<span class="reactions-count">1</span>
Enter fullscreen mode Exit fullscreen mode

So "dev.to comment reactions cannot be read" was false while "the dev.to comments API exposes no reaction count" was true, and I had filed the first one.

Only the fourth verdict held up. Our own site has no analytics package installed at all, so nothing is collecting and there is no endpoint to go find. That one stays on the list until somebody installs a collector.

Getting one out of four right is a bad score for my own judgment, and the mistake is the same every time. I tested a single access path and then wrote a conclusion about the entire surface. An API missing a field tells you about that API. The rendered page is a different program with a different serializer, and a public read-only endpoint is a third thing again.

So before you record something as unreadable, knock on the other doors:

  • the official API
  • the rendered HTML of the item's own permalink
  • a public or unauthenticated endpoint, which read-only data often has
  • an embed, feed, or mobile view

Then write down which one you actually tried. "Cannot be read" rots into a permanent excuse. "The v2 comments API returns no reaction field, and I have not checked the rendered page" rots into a to-do, which is the outcome you want.

Fixing this opened a second trap, and I walked into it about ten minutes later. With the Vanilla endpoint finally answering, I inserted its comments into my metrics table with a score of 0, because the response carried no score field. A gap in a table announces itself. A zero does not: it reads as evidence, it survives every join, and it quietly pulls down any average computed over it. I went back and corrected those three rows to NULL.

If a surface did not tell you the number, store NULL and record why. An absent field is not a zero, and the moment you let it become one you have manufactured data.

The other thing worth doing is scoping your selector to your own item. These pages render entire threads, so a first match on .reactions-count returns whichever comment sits highest in the DOM, which is usually a stranger's. I nearly wrote somebody else's engagement numbers into my own table, and that would have been harder to notice than an empty column, because the value looks perfectly reasonable.

Top comments (0)