Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Natural keys and RESTful URLs

I have a RESTful API that I'm designing which uses numeric primary keys for all of its resources. However one type of resource has a convenient natural key, which I'd like to be able to use as an optional way to specify the individual resource. For consistencies sake all resources will be accessible via their primary key.

As it stands, I can do this (assuming 23 is the primary key):

mysite.com/api/v0/sites/23/

However, I'm wondering if there's an idiomatic way to specify an alternate natural key for a resource.

So far I was thinking of doing something like this:

mysite.com/api/v0/sites/?domain-name=someothersite.com/

So an individual site resource would be accessible by both its primary key and a natural key (its domain name). My primary concern is doing this in and idiomatic fashion, seeing as I'd like to make the API as straightforward to use as possible.

like image 201
rectangletangle Avatar asked Jul 10 '14 04:07

rectangletangle


People also ask

What is a RESTful URL?

Although URLs containing parameters within the query string do themselves conform to REST constraints, the term “REST-style URL” is often used to signify a URL that contains its parameters within the URL file path, rather than the query string.

What is natural key in Django?

It is for these reasons that Django provides natural keys. A natural key is a tuple of values that can be used to uniquely identify an object instance without using the primary key value.

What is natural key in database?

A natural key is a column or set of columns that already exist in the table (e.g. they are attributes of the entity within the data model) and uniquely identify a record in the table. Since these columns are attributes of the entity they obviously have business meaning.

What is natural key business key in SQL?

A natural key (also known as business key or domain key) is a type of unique key in a database formed of attributes that exist and are used in the external world outside the database (i.e. in the business domain or domain of discourse).


2 Answers

In your particular situation, the primary key (integer) can always easily be differentiated from the domain name (string including a period). It seems perfectly valid (and intuitive) to allow both in the same location of the URL:

mysite.com/api/v0/sites/23
mysite.com/api/v0/sites/someothersite.com

Documenting it is straightforward too, as each is a unique identifier for a site:

mysite.com/api/v0/sites/{id}
  id: primary key or fully-qualified domain name
like image 119
Mike Dunker Avatar answered Oct 05 '22 09:10

Mike Dunker


I've also struggled with finding a satisfying answer to this question. I had already started to implement the same as Mike Dunker suggested, but eventually encountered some resources for which it is just not possible to distinguish between the surrogate key and the natural key. It was then that I realized I'd rather have a uniform approach to this instead of mixing different ways - like you say, something idiomatic.

One other approach I found is described at http://soabits.blogspot.de/2013/10/url-structures-and-hyper-media-for-web.html (under "Natural keys, surrogate keys, URL aliases and resource duplication").

The idea is to define one of the two possible key schemes as the canonical one and realize the other one by adding a segment to the URI and using a HTTP 303 (See Other) to redirect to the canonical URI.

So in your example, you could have mysite.com/api/v0/sites/23/ as the canonical ID and mysite.com/api/v0/sites/domain-name/someothersite.com/ would reply with HTTP 303 and a location header containing mysite.com/api/v0/sites/23/ (or the other way round). Using redirects for URI aliases instead of "duplicating" the same resource is useful for the reasons named at http://www.w3.org/TR/webarch/#uri-aliases.

The reason why I did not go with this solution either is the additional HTTP round trip, which may be too expensive in our project setup.

like image 23
Hein Blöd Avatar answered Oct 05 '22 09:10

Hein Blöd