Responses include related resource links
Why it matters
A response that includes userId but no information about how to fetch the user forces every consumer to hardcode the URL pattern /api/v1/users/{userId}. When that pattern changes, every consumer breaks — and there is no machine-readable artifact that could have warned them. iso-25010:2011 compatibility.interoperability is the direct gap: the API returns foreign keys but not the means to navigate them, making the API partially self-describing at best and requiring consumers to maintain their own URL construction knowledge.
Severity rationale
Info because missing resource links are a navigability improvement rather than a functional defect — consumers can work around the gap by hardcoding URL patterns, but it makes the API less self-documenting.
Remediation
Add basic resource linking to make responses partially self-describing. Even just self URLs are a meaningful improvement over bare IDs:
// Before -- ID only, consumer must know URL pattern:
{
"id": "order-123",
"userId": "user-456"
}
// After -- with links:
{
"id": "order-123",
"userId": "user-456",
"_links": {
"self": "/api/v1/orders/order-123",
"user": "/api/v1/users/user-456"
}
}
Start with self links on every resource — that alone lets consumers build shareable URLs and canonical references. Add related resource links for the two or three relationships consumers navigate most frequently.
Detection
-
ID:
resource-linking -
Severity:
info -
What to look for: Check whether API responses include links or references to related resources that consumers commonly need to navigate to. Look for: HATEOAS-style
_linksobjects,urlfields pointing to related endpoints,idfields for related resources that consumers can use to construct URLs. The question is: can a consumer navigate the API starting from any response, or do they need to hardcode URL patterns? This is aspirational for most APIs -- full HATEOAS is rare, but basic linking (e.g., including aselfURL or related resource URLs) improves ergonomics significantly. -
Pass criteria: Count all resource relationships across responses (foreign key IDs referencing other resources). Responses include at least 1 form of basic resource linking -- either
selfURLs on resources, URLs for related resources, or consistent ID fields that follow a documented URL pattern consumers can construct. -
Fail criteria: Responses include no linking information. Related resource IDs are present but the URL pattern to fetch them is not documented (e.g.,
{ "userId": "abc" }with no way to know the URL is/api/v1/users/abc). Consumers must hardcode URL construction for every resource relationship. -
Skip (N/A) when: The API has 3 or fewer endpoints with no resource relationships. Also skip for GraphQL (relationships navigated via query structure, not links) and gRPC (links are not a convention).
-
Detail on fail: Note what's missing (e.g., "Order response includes
userIdbut no URL to fetch the user. Product responses includecategoryIdbut the pattern to fetch a category is not documented anywhere. NoselfURLs on any resource."). Max 500 chars. -
Remediation: Add basic resource linking to improve API navigability:
// Before -- ID only, consumer must know URL pattern: { "id": "order-123", "userId": "user-456", "items": [{ "productId": "prod-789" }] } // After -- with links: { "id": "order-123", "userId": "user-456", "items": [{ "productId": "prod-789" }], "_links": { "self": "/api/v1/orders/order-123", "user": "/api/v1/users/user-456", "items": "/api/v1/orders/order-123/items" } }Even partial linking (just
selfURLs) is a significant improvement.
External references
- iso-25010:2011 · compatibility.interoperability — Interoperability — resource links enable consumer navigation without hardcoded URL patterns
Taxons
History
- 2026-04-18·v1.0.0·Initial import from api-design·automated