Suppose we're working with a database that has the following relation:
CREATE TABLE Author (
first_name VARCHAR NOT NULL,
last_name VARCHAR NOT NULL,
birth_date DATE NOT NULL,
death_date DATE,
biography TEXT,
UNIQUE(first_name, last_name, birth_date)
);
In the real world, it's highly, highly improbable that two authors with the same first and last name will have been born on the exact same day. So we consider the combination of an author's first name, last name, and birth date to be a natural key.
However, for the purposes of joining tables and creating foreign keys, this is a bit painful because it means we need to store these three pieces of information over and over and over in our tables. Maybe we have a BookAuthor
relation associating Author
s with Book
s.
So we create a serial ID (or a UUID if we wanted to) and treat it as the primary key:
CREATE TABLE Author (
id SERIAL PRIMARY KEY,
first_name VARCHAR NOT NULL,
last_name VARCHAR NOT NULL,
birth_date DATE NOT NULL,
death_date DATE,
biography TEXT,
UNIQUE(first_name, last_name, birth_date)
);
However, based on the reading I've done here on StackOverflow and other sites, it seems you never want to expose your primary key to the end user because doing so may allow them to ascertain information that they should not be able to. If this were a situation involving user accounts, for example, and we decided to use serial IDs (we shouldn't, but humor me), then someone could potentially figure out how many total users we have in our database, which isn't information that they should see. In this particular case, someone knowing how many total authors we have isn't really a big deal. But I want to follow best practices.
So, if I were to design a REST API for this database, would it be acceptable to use the natural key to uniquely identify resources (Author
s) instead of using serial IDs? For example:
https://www.foo.bar/authors/?first=:Terry&last=Pratchett&dob=19480424
My reasoning here is that there's no way for an end user to know what serial ID corresponds to this author in order to query for them.