Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check availability and reserve usernames in CouchDB

Tags:

couchdb

I have a registration page which asks the user to enter a username and email address.

I need to check to see if the username + email is available. How to do I do this with just one HTTP request?

BTW, the username is used as the docID.

What I'm doing right now is checking to see if the docID exists, then using a view to check for the availability of the email address, but that's 2 HTTP requests.

I thought about using a view to emit [ username, email ] as the key and query the view with a "key" param = [ username, email ]. But this won't work if the username and email belong to different existing users.

like image 680
Jason Avatar asked Nov 14 '22 09:11

Jason


1 Answers

Jason. Sam's solution is quite helpful however as you say, it may not be a perfect fit for you. I can think of two other options.

Pretend for a moment you are back in SQL. What is the primary key of a user? It is neither the username nor the email but both columns. Same for CouchDB.

So, to absolutely guarantee uniqueness, the answer is simple: it must be the doc _id. For example, for user "jason" with email "[email protected]", POST this doc:

{ "_id": "jason:[email protected]",
  "other stuff": "blah blah blah"
}

That is an atomic, transactional, user creation. It could:

  • Succeed, so now you have your new user document
  • Fail because that id already exists and you (intentionally) forgot the _rev property. Great, that user/email combo is already taken!

Of course, to simply check if the name is available you can GET /db/jason:[email protected]. (You could prefix the id like the _users database does, like users:jason:[email protected]—it's up to you.) Then you can POST it back later. There is a chance it will be taken in the mean time but that's normal in all "check first, reserve later" forms which are quite common on the web now.

The second idea is more just to think carefully about your situation. You said that two users can have the same username and email. That sounds odd. Maybe I read wrong. Here are some things to think about:

  • Almost nobody shares an email account with somebody else. Why not make that the actual login name? It's good enough for Facebook. Then the "username" can just be a user's nickname or handle within the system, just a property in the user document.
  • Two HTTP requests may not be that bad. I think about it this way:
    • If this is a 3-tier architecture (dedicated webserver, couchdb backend), then two HTTP requests is no big deal
    • If it is a 2-tier or hybrid (where browsers hit couchdb directly), then strongly consider using CouchDB for authentication, described in the CouchDB book. CouchDB can handle logins for you, with a form or AJAX. It is not perfect for every situation but you get great bang-for-the-buck.
like image 118
JasonSmith Avatar answered Dec 21 '22 10:12

JasonSmith