

Show HN: I made a simple persistent counting API - dustyreagan
http://arbitrarycounter.com/

======
dragonwriter
Incrementing or decrementing a counter is neither side-effect-free nor
idempotent, and GET should generally be both, so you really shouldn't use GET
for those operations. [1]

POST would probably be the usual choice for these operations. (Though, since
you aren't really creating a subresource but are instead performing a defined
transformation on an existing resource, you could probably make a case for
PATCH.)

Web APIs are protocols implemented on top of HTTP, and should respect the
semantics of HTTP unless there is a clearly-identified compelling reason not
to.

[1]
[http://tools.ietf.org/html/rfc2616#section-9.1](http://tools.ietf.org/html/rfc2616#section-9.1)

~~~
hnriot
why should they respect the semantics? Those were arbitrary and out dated. I
don't see any need for that.

~~~
wcarss
Web crawlers and web page views index using GET; if GET affects your server
state, so do page views and indexing.

GET is idempotent. That's not outdated, and it's not arbitrary: it is
literally stated in the protocol specification. It's a useful distinction
created and used by professionals to maintain sanity in complex schemes of
communication.

Please do not ignore technical details because you think you're smarter than
everyone else on the planet, or that the problems they solved a decade ago
somehow went away in the face of node.js.

edit: Just in case you (or anyone reading this) is unaware of it,

[http://www.ietf.org/rfc/rfc2616.txt](http://www.ietf.org/rfc/rfc2616.txt) (or
pretty: [http://pretty-rfc.herokuapp.com/RFC2616](http://pretty-
rfc.herokuapp.com/RFC2616))

Find Section '9.1 Safe and Idempotent Methods'.

~~~
mnutt
_Naturally, it is not possible to ensure that the server does not generate
side-effects as a result of performing a GET request; in fact, some dynamic
resources consider that a feature. The important distinction here is that the
user did not request the side-effects, so therefore cannot be held accountable
for them._

I think that, depending on what his API is trying to do, GETing a counter URL
to increment it could be acceptable if his service's main purpose is to be
accessible via client-side javascript.

That being said, once you go down that road you have to begin taking into
account everything that may depend on GET idempotence: send back proper
caching headers as well as busting caches from the client side, decide whether
or not you want to block javascript-parsing web crawlers, etc.

------
dustyreagan
I was doing some usability testing in one of my webapps and needed a simple
way to count conversions. There are lots of A/B testing solutions out there,
but I just wanted a persistent count I could increment on specific user
actions. So I created the ArbitraryCounter.com.

I find it useful, but I'm wondering if anyone else might. What do y'all think?

PS. This is WAY beta, and mainly a proof-of-concept. But I'll continue
developing it if there's an interest it.

~~~
ankurpatel
Can someone explain how counters can be so hard to implement ourselves that we
need to use this?

~~~
terabytest
It's probably not that they're hard, but rather that they might require some
boilerplate code and bloat that somebody might want to offload to an external
service like this one.

------
Jake232
I think you should be able to incr/decr by more than 1. Maybe allow
[http://arbitrarycounter.com/vb/fruit/apples+N](http://arbitrarycounter.com/vb/fruit/apples+N)
where N can be any integer > 0

~~~
dustyreagan
I added an IncrementBy and DecrementBy variable you can pass in your POST
request, and update the documentation. How's that work for ya'?

------
pwf
GET should never modify data. I would recommend changing that to a POST before
something indexes it and decides to crawl it every 5 minutes. See here for
more reasons: [http://stackoverflow.com/questions/705782/why-shouldnt-
data-...](http://stackoverflow.com/questions/705782/why-shouldnt-data-be-
modified-on-an-http-get-request)

I realize this isn't supposed to be highly accurate, but it's something to
keep in mind if it continues to grow.

~~~
dustyreagan
Agreed. I updated the site and docs. Thanks! :)

------
geuis
I love simple api's like this. Its kind of the same mental model I keep around
[http://jsonip.com](http://jsonip.com). A simple service that does one thing
really well. Its been working well and has grown to millions of requests a
day.

Keep working on this, I can see several uses already.

~~~
ancarda
>millions of requests a day.

I'm interested to know how much it takes to run jsonip? Does it cost a lot?

Edit: I've just seen the Pro version. Are you turning jsonip into a freemium
model?

~~~
geuis
It's a node.js app that has until recently been a single-process app. I just
integrated clustering to take advantage of the extra cores Linode gave me.
It's a simple but high traffic service and node has handled it like a champ. I
have a relatively inexpensive account with Linode that so far has suited the
site's traffic just fine.

I'm exploring the idea of offering a higher-tier service. The general feature
list is outlined on getjsonip.com but pricing isn't finalized. I'm still
collecting signups and feedback right now.

------
egonschiele
> All URLs are public. We recommend using a unique group name to avoid
> collisions with other users.

So anyone can increment your counter without you knowing? Seems like this
means you can never rely on the count being right.

As a side note, the link on the bottom is broken.

~~~
terabytest
Unless they know what counter you're using or you make it public, it's
unreasonable that anyone could mess with your counter.

~~~
egonschiele
This would be an example of security through obscurity.

~~~
cobbal
Yes and no. You could argue that use of passwords or private keys is security
through obscurity, but that definition is pretty meaningless. Security through
obscurity doesn't really apply when you can make the search space arbitrarily
(often exponentially) big very cheaply, as is the case of URLs here.

------
frankcaron
"There's an API for that" is the new "there's an app for that".

~~~
meowface
Yep. I understand this is just a little toy thing, but people are really
trying to start businesses off of "APIs" that do not much more than OP's.

The whole point of an API is that you defer a significant amount of serverside
processing and logic to a remote host, and receive a nicely formatted and
machine-readable response. You have to deal with the overhead of a TCP
connection (handshaking / RTT), an HTTP request, and an HTTP response. If
you're doing that every time a user visits your web page (or app view or
whatever), especially multiple times, then you better have a good reason for
doing so.

