Будь ласка, припинить виставляти автоінкрементні ідентифікатори назовні. В урлах, в API, будь-де. З ними погано все:
- Ти видаєш назовні дані про те, скільки в тебе цих сутностей. Можливо тобі взагалі це фіолетово, особливо під час розробки, але бізнес-сторона не скаже тобі дякую потім за те, що всі конкуренти в курсі, як добре йде твій бізнес.
- Ти даєш дуже простий інтерфейс для парсингу всіх даних від тебе: звичайним циклом можна забрати абсолютно все.
- Вони виглядають однаково. Коли в тебе багато сутностей і багато айдішників, в якийсь момент ти в них заплутаєшся. :)
- Жодної семантики в них нема. Коли починається якийсь дебаг з 10-20 різними типами сутностей і айдішників — голова закипає.
- Ти їх видаси у своєму JSON'і як числа і тоді шансів щось змінити в тебе буде обмаль. Трохи нижче про це напишу.
То що ж робити?
- Найкраще — то коли ти можеш виставити назовні щось семантичне, slug. Перетворити у латинку нижнім регістром заголовок поста, назву фільтра чи його значення — це все нескладно, і якщо кількість сутностей дозволяє, нормально працює унікальним ідентифікатором.
- Якщо назва не дозволяє унікальності, можна додати до неї айдішник. Так, першу проблему ти не закриваєш, але всі інші закриваєш.
- Нема якоїсь конкретної назви або треба щось коротке? Візьми hashids, вони закодують твої циферки і якусь сіль у не дуже довгий рядок, і імплементація настільки проста, що є фактично для всього. На додаток, якщо з імплементації вирізати можливість мати списки, то результат ще й трошки коротшим стає IIRC. Плюс можна дати власну абетку, щоб не було схожих літер і простіше було людям прочитати це (для нас цей кейс важливий був, коли люди дзвонили у кол-центр з номерами замовлень).
- Комбінація назви та hashids, щоб таки не палити айдішник назовні.
- Проблему з однаковим виглядом можна, для найважливіших кейсів, вирішити префіксом, або якимось форматом. В Амазона формат номера замовлення
\d{3}-\d+-\d+
(вчіть регекспи), в КастиK[\d\w]+
, різне можна зробити. Це, до речі, дуже корисно для кількох найважливіших сутностей, коли вони регулярно вилазять в різних місцях, особливо у спілкуванні нетехнічних людей. - Якщо фантазії взагалі не вистачає, візьми UUID4. Так, він довгий, це неможливо сказати вголос іншій людині, ти їх не будеш розрізняти між собою, але ти хоча б закриєш перші дві проблеми та не будеш видавати зайвих даних на волю.
Про числа. Всі фронтендери поділяються на два типи: тих, кому пофіг на типізацію (жс), і тих, хто робить життя людей нестерпним (всі інші). Уявімо, що ви писали першу реалізацію якомога швидше і всюди повидавали айдішники. А потім захотіли з них переїхати на що завгодно: на префікси, на base64, на UUID. Але не можете, бо всі клієнтські апки ваші айдішники розбирають як число і строку туди не підкласти ніколи. Для міграції залишається дві опції — від'ємні числа і якась хитра арифметика (додайте трильйон і сподівайтеся що ваші клієнти розумініші за int32 🤣).
Тому ніколи — чуєте, ніколи — не віддавайте ідентифікатори як число. Зробіть {"id": str(id)}
, тоді у вас будуть шанси у майбутньому. Тим паче якщо ви віддасте їх як число, якийсь дуже розумний™ фронтендер десь помітить закономірність і щось оптимізує. Чи то швиденько пагінацію свою намутить (до речі, використовуйте курсори), чи ще якоюсь арифметикою займеться (деякі події зі свого життя я навіть не хочу розповідати 😅).
Найголовніше. Який би ти айдішник не згенерував, обов'язково запиши його в базу. Не треба оцих муток "я в апі розберу hashid назад у цифру і зроблю запит по ній", це, по-перше, довше, а, по-друге, ти задовбешся шукати руками в базі, логах та обмінах повідомленнями. Просто консистентно ідентифікуй всюди цю сутність її айдішником. Може і FK на цей айдішник варто робити, тут вже я не певен. :)