swapi icon indicating copy to clipboard operation
swapi copied to clipboard

Feature request: Return all IDs as v4 UUID

Open Joshfindit opened this issue 8 years ago • 6 comments

UUIDs have the benefits of being globally unique, which means that if someone brings in data from an API that returns a UUID, they can use that UUID as the internal ID as well.

If IDs are returned sequentially, the API caller have to create a different ID internally and then map it to the external ID for later updates.

(Also, for those that like an orderly database, internal UUIDs avoid the problem of leaving gaps in a sequence if removing/reordering things)

Joshfindit avatar Mar 17 '17 14:03 Joshfindit

Hey @Joshfindit thanks for the feedback. I am 100% behind using UUID's instead of single integers. I tend to do this in any new system I create and I recommend it to everyone who asks for advice. The ID's in SWAPI are integers that just happen to be the primary key too (simplicity back when this was a side project). Interestingly I do get people asking me why certain ones don't exist (for example: https://github.com/phalt/swapi/issues/51) and this is because humans see incrementing numbers and assume some logic/relationship there. I do regret doing that, now!

I'm 100% behind someone updating the API so long as backwards compatibility is not affected (we have 100+ integrations and we can't guarantee they are fully HATEOAS and haven't hard-coded anything). Feel free to open a PR and start working on it and I'll be happy to give feedback.

phalt avatar Mar 20 '17 11:03 phalt

Excellent. If you don't mind, I'll add some notes on this issue; it's interesting enough to keep me coming back and hacking away at it, but I'm a B2C sysadmin turned hobby-dev with some experience in Ruby/Vue.js/Javascript/HTML/CSS, so I might not be the right person to implement it, but who knows I may end up adding Python to the list. :)

Joshfindit avatar Mar 21 '17 00:03 Joshfindit

Possible avenues to explore (feel free to comment/cherry-pick):

  • Add a UUID field to all responses
  • Any objects that do not have a UUID assigned already get one generated when committing to the database
  • accept UUIDs on the API endpoints, and do a simple:
if id_from_the_api_call.length == 36:
   print "assume UUID"
else:
   print "Continue with the current logic"
  • One day just return UUIDs as the id for all responses. Some chance that end-users have hard-coded 8-bit integers as the IDs, but besides that is there any risk to just suddenly returning UUIDs as the ID for all responses? (if the end-user is relating two charaters by querying the API, and they just accept whatever is given as the ID, then it would make no difference whether it refers to 22, 8764, or a7b7f15a-757a-4b46-bc02-ad7b2be7096c. Same for list > query character.)
  • /v2 the API and do UUID only

Joshfindit avatar Mar 21 '17 01:03 Joshfindit

Django supports UUID fields by default: https://docs.djangoproject.com/en/1.10/ref/models/fields/#uuidfield

So that's point one resolved :)

Python also has built in uuid checking, so you don't need to do just the length check.

phalt avatar Mar 21 '17 10:03 phalt

Excellent. Putting this model code here for reference: uuid = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

Looks like it will automatically generate without any massaging needed.

Joshfindit avatar Mar 21 '17 13:03 Joshfindit

As for

Python also has built in uuid checking, so you don't need to do just the length check.

Looks like there's a good definition of a function for is_valid_uuid on Stackoverflow

Basically:

try:
    uuid_obj = UUID(uuid_to_test, version=version)
except:
    return False

So then:

if is_valid_uuid(id_from_the_api_call):
   print "Query the database by UUID"
else:
   print "Query the database by integer"

Joshfindit avatar Mar 21 '17 13:03 Joshfindit