简体   繁体   中英

Informative vs unique generated ID in REST API

Designing a RESTful API. I have two ways of identifying resources (person data). Either by the unique ID generated by the database, or by a social security number (SSN), entered for each person. The SSN is supposedly unique, though can be changed.

Using the ID would be most convenient for me, since it is guaranteed to be unique, and does not change. Hence the URL for the resource, also always stays the same:

GET /persons/12

{
  "name": Morgan
  "ssn": "840212-3312"
}

The argument for using SSN, is that it is more informative and understandable by API clients. SSN is also used more in surrounding systems:

GET /persons/840212-3321

{
  "name": Morgan
  "id": "12"
}

So the question is: Should I go with the first approach, and avoid some implementation headaches where the SSN may change. And maybe provide some helper method that converts from SSN to ID?

Or go with the second approach. Providing a more informative API. Though having to deal with some not so RESTful strangeness where URL:s might change due to SSN changes?

URL design is a personal choice. But to give you some more examples which differ from those Ray has already provided, I will give you some of my own.

I have a user account resource and allow access via both URIs:

/users/12

and

/users/morgan

where the numerical value is an auto_incremented ID, and the alphabetic value is a unique username on the system specified by the user. these resources are uncachable so I do not bother about canonicalisation, however the /users page links to the alphabetic forms.

No other resources on my system have two unique fields, so are referred to by IDs, /jobs/123 , /quotations/456 .

As you can see, I prefer plural URI segments ;-)
I think of "job 123" as being from the "jobs" collection, so it seems logical to have a "jobs" resource, with subresources for each job.

You do not need to have a separate /search/ area for performing searches, I think it would be cleaner to apply your search criteria to the collection resource directly:

/people?ssn=123456-7890  (people with SSN matching/containing "123456-7890")
/people?name=morgan      (people who's name is/contains "Morgan")

I have something similar, but use only the first letter as a filter:

/sites?alpha=f

Lists all sites beginning with F. You can think of it as a filter, or as a search criteria, those terms are just different sides of the same coin.

Good to see someone taking time to think about their Resource urls!

I would make a Url with the unique id to provide resource to a single user. Like:

http://api.mysite.com/person/12/

Where 12 is your unique ID. Note that I also prefer the singular 'person'....

Regardless, the url should return:

{
  "ssn":  "840212-3312"
  "name": "Morgan"
  "id": "12"
}

However, I would also create a general search URL that returns a list of users that match the parameters (either a json array or whatever format you need). You can specify search parameters as get params like this:

 http://api.mysite.com/person/search/?ssn=840212-3312

Or

 http://api.mysite.com/person/search/?name=Morgan

These would return something like this for a single search hit--note it's an array, not a single item like the unique id url that points directly to a single user.

[{
  "ssn":  "840212-3312"
  "name": "Morgan"
  "id": "12"
}]

This search could then be later augmented for other search criteria. You might only return the unique id's via the search Url--you could always make a request to the unique id url once you've got it from the search...

I would suggest that you use neither. Generate resource IDs that are unique both to a single user of your API and across all other resources (including other users' resources).

Using the unique database ID is not ideal for a couple of reasons. First, API resources and database records won't necessarily always be 1-to-1 even if you have designed it that way today. Second, you might change to a different data store that would generate different format unique ids.

Also, it is good practice to separate out the ID from other resource properties, such as SSN (as an aside I hope you are storing SSN in a very secure manner, but that's another topic). If for whatever reason an SSN changed, more than one API resource was associated with the same SSN, or you decide that piece of data is not needed someday, you don't want to have to change the ID.

One pattern is to prepend the unique ID with a few characters that indicate the resource type. For example if User is a resource type in you API, a generated unique ID would be something like USR56382 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM