Identifier Design with URIs¶
1. URI Fundamentals¶
REST APIs use Uniform Resource Identifiers (URIs) to address resources. A URI is the unique name and address of a resource in your API's ecosystem.
- API Designers: Should strive for URIs that are clean, readable, and intuitive. A URI should reflect the resource model, not the underlying database schema.
- API Clients: Should treat URIs as opaque links. This follows the HATEOAS (Hypermedia as the Engine of Application State) principle—clients should follow links provided by the server in resource representations rather than manually constructing URIs via string concatenation.
The Generic URI Syntax¶
Defined by RFC 3986, the generic structure of a URI is:
The authority component consists of:
¶
2. URI Format Rules¶
Rule: Forward slash (/) indicates hierarchical relationships¶
The forward slash is the primary delimiter used in the path to indicate a parent-child relationship between resources. * Example: /leagues/seattle/teams/trebuchet
Rule: Do not include trailing forward slashes (/)¶
A trailing slash adds no semantic value and may cause confusion for caches or result in 404 errors in strict routing systems. * Modern Standard: If a client requests /shapes/, the server should ideally issue a 301 Moved Permanently redirect to /shapes. Every character in a URI contributes to its identity; technically, these are two different resources.
Rule: Use hyphens (-) for readability; avoid underscores (_)¶
Hyphens are the web's standard word separator. * Reason: Hyperlinks are often underlined in documentation and UIs. This underline can hide an underscore (making my_resource look like my resource), leading to input errors.
Rule: Prefer lowercase letters in URI paths¶
While the scheme and host are case-insensitive, RFC 3986 defines the path component as case-sensitive. To prevent 404 errors caused by simple typos, lowercase is the mandatory industry default.
Rule: Do not include file extensions¶
Artificial extensions (e.g., .json, .xml) should be avoided. Use Content Negotiation via the Accept and Content-Type HTTP headers. * Anti-pattern: GET /transcripts/2026/fall.json * Standard: GET /transcripts/2026/fall (with Header Accept: application/json)
3. URI Authority & Versioning Design¶
Rule: Consistent subdomain names for APIs¶
Identify the service owner in the TLD and use a dedicated api subdomain to isolate traffic and apply specific security (CORS) policies. * Example: https://api.soccer.restapi.org
Rule: Consistent subdomain names for developer portals¶
By convention, developer-facing documentation and onboarding should live on a developer or docs subdomain. * Example: https://developer.soccer.restapi.org
Rule: API Versioning (Modern Expansion)¶
API versioning is critical for backward compatibility. The most common standard is path-based versioning, placed as the first segment. * Standard: https://api.example.com/v1/users
4. Resource Modeling¶
The URI path conveys the API's resource model. Each segment separated by a slash corresponds to an addressable resource in the hierarchy.
If the URI is http://api.soccer.restapi.org/leagues/seattle/teams/trebuchet, the design implies: * /leagues/seattle/teams (The collection of teams) * /leagues/seattle (The specific league) * /leagues (The root collection) * / (The API root/docroot)
5. Resource Archetypes¶
A REST API should align each resource with exactly one of these four archetypes to maintain a consistent interface.
Document¶
A singular concept, akin to a database record or object instance. It can contain fields and links to related resources. * Naming: Singular noun. * Example: /users/morgan
Collection¶
A server-managed directory of resources. The server decides the URI of new items added to it (usually via POST). * Naming: Plural noun. * Example: /users
Store¶
A client-managed resource repository. The client decides the URI when putting resources in (usually via PUT). * Naming: Plural noun. * Example: /users/morgan/favorites/soccer (Client decides 'soccer' is the ID).
Controller¶
Models a procedural concept or "action." Like a function, it has inputs and outputs. * Naming: Verb or verb phrase. * Example: POST /alerts/245743/resend
6. URI Path Design¶
Rule: Naming Conventions¶
- Documents: Singular noun (
/players/claudio). - Collections/Stores: Plural noun (
/players). - Controllers: Verb (
/register,/reindex).
Rule: Variable segments should use identity-based values¶
Static segments are chosen by the designer; variable segments represent unique IDs. * 2026 Security Note: Avoid sequential integer IDs (/users/1). Use UUIDs or ULIDs (Sortable Unique IDs) to prevent IDOR (Insecure Direct Object Reference) and data harvesting.
Rule: Do not use CRUD names in URIs¶
HTTP methods already describe the action. Using them in the URI is redundant and non-RESTful. * Bad: POST /deleteUser?id=1 or GET /users/1/delete * Good: DELETE /users/1
7. URI Query Design¶
Queries identify variations or derivatives of a resource (filtering, sorting, and searching).
Rule: Filter collections or stores with query parameters¶
- Example:
GET /cars?color=red&status=available
Rule: Paginate results using query parameters¶
While pageSize and pageStartIndex are classic, modern high-scale APIs prefer Limit/Offset or Cursor-based pagination. * Limit/Offset: ?limit=20&offset=100 * Cursor-based (2026 Industry Standard): ?after=Y29udGVudA&limit=20. Cursors are opaque strings that point to the last record seen, ensuring stability even if data is added during pagination.
Rule: Use query for sorting and field selection¶
- Sorting:
GET /users?sort=-created_at(The-prefix often denotes descending order). - Sparse Fieldsets:
GET /users/1?fields=name,email.
8. Privacy and Security (New Expansion)¶
Rule: Never put PII in URIs¶
Personally Identifiable Information (PII) like emails or phone numbers should be avoided in URIs, as URIs are often logged in plaintext across proxies and server logs. Use a non-identifying user_id.
Rule: No sensitive data in query strings¶
Query parameters are visible in browser history and server logs. Never pass API keys, passwords, or tokens in the query string. Use the Authorization header.