REST API - URL 中的字符串或数字标识符

REST API - string or numerical identifier in URL

我们正在为我们的平台开发 REST API。假设我们有 organisationsprojects,并且 projects 属于 organisations

阅读后,我倾向于在URL中使用数字ID,这样一些URL就会变成(比如前缀为/api/v1):

/organisations/1234
/organisations/1234/projects/5678

但是,我们想为我们的前端UI使用相同的URL结构,这样如果你在浏览器中输入这些URL,你会得到相关的响应中的网页而不是 JSON 文件。与您在 Facebook 或 Github.

等网站上看到相关人员和组织名称的方式大致相同

使用这个,我们可以得到类似的东西:

/organisations/dutchpainters
/organisations/dutchpainters/projects/nightwatch

看起来 Github 实际上以同样的方式暴露了 their API

对于 URL 定义使用名称而不是 ID,我能想到的优点和缺点如下:

优点:

缺点:

尤其是后者,似乎成了后方的潜在隐痛。尽管如此,在阅读 this answer 之后,我几乎确信使用字符串标识符,因为从约定的角度来看它似乎没有什么不同。

我的问题是:

两者结合使用很常见:

/organisations/1234/projects/5678/nightwatch

最后一部分被忽略但用于使 url 更具可读性。

在您的情况下,对于多级集合,您可以尝试使用这种格式:

/organisations/1234/dutchpainters/projects/5678/nightwatch

如果有人写

/organisations/1234/germanpainters/projects/5678/wanderer

它仍然会映射到伦勃朗,但应该没问题。这将为编辑名称留出空间,而不会弄乱 url:s 已经准备就绪。此外,如果您真的不需要名称,则名称不必是唯一的。

Reserved HTTP characters: such as “:”, “/”, “?”, “#”, “[“, “]” and “@” – These characters and others are “reserved” in the HTTP protocol to have “special” meaning in the implementation syntax so that they are distinguishable to other data in the URL. If a variable value within the path contains one or more of these reserved characters then it will break the path and generate a malformed request. You can workaround reserved characters in query string parameters by URL encoding them or sometimes by double escaping them, but you cannot in path parameters.

https://www.serviceobjects.com/blog/path-and-query-string-parameter-calls-to-a-restful-web-service

不再推荐数字连续 ID,因为它很容易猜测您数据库中的记录,有些人可能会使用它来获取他们无权访问的信息。

使用数字 ID 是因为在数据库中它是固定长度的存储,这使得数据库的索引变得容易。例如 INT 在 MySQL 中有 4 个字节,而 BIGINT 是 8 个字节,所以数字在内存中具有相同的长度(INT 中的 100 与 200 具有相同的长度)因此很容易索引和搜索记录。

如果数据库中有很多条目,那么使用 VARCHAR 字段进行索引不是一个好主意。您应该使用像 CHAR(32) 这样的固定宽度字段并用空格填充差异,但是您必须在程序中添加逻辑以在搜索数据库时处理差异。

另一个想法是使用 slug,但在这里你应该考虑到一些记录可能有相同的 slug,这取决于你用什么来形成那个 slug。 https://en.wikipedia.org/wiki/Semantic_URL#Slug

我建议使用 UUID,因为它们具有相同的长度并且可以轻松解决此问题。