
Let API addresses follow the business
An address can say more than which record to open. It can express that a task belongs to a particular list, or that a collection sits within an organization.
Wildo derives those routes from the relationship model. You choose when parent context is required, optional or absent, and the API uses that choice consistently when constructing addresses.
The relationship therefore connects the application’s business structure to the way an integration reaches it.
Example — Create a task in the intended list
An integration creates a task under a list’s address. The parent in that address identifies the list the write belongs to; conflicting parent information in the submitted data does not silently send the task elsewhere.
For engineers
Declare routing on the relationship
The route builder consumes the resource’s assembled relationships and operation variants. REQUIRES_CONTEXT includes the parent in the route, OPTIONAL_CONTEXT permits contextual and standalone forms, and STANDALONE leaves that parent out of routing.
This list-to-task relationship from Wonder Todos’ tasks-manager.relationships.ts uses optional context. A standalone source comment is omitted:
createResourcesRelationship(
TasksManager_ResourceType.TODO_LISTS, TasksManager_ResourceType.TODOS,
ResourceRelationshipCardinality.ONE, ResourceRelationshipCardinality.MANY,
{
nature: RelationshipNature.COMPOSITION,
foreignKeyField: 'todoListId',
accessScopeStrategy: ResourceRelationshipAccessScopeStrategy.OPTIONAL_CONTEXT,
contextPolicy: {
operationOverrides: {
[CoreResourceOperation.LIST]: { enabled: false },
[CoreResourceOperation.SEARCH]: { enabled: false },
}
}
}
),
todoListId names the link between the two records. The cardinalities describe one list with many tasks. OPTIONAL_CONTEXT allows the list relationship to contribute a nested address without making it the only address. Other required parents in the graph, such as organization scope, still apply.
Let the operation choose the rest of the address
Collection and entity operations use different address shapes: entity paths include the record identifier, while collection operations address the collection. Search, count and bulk companions have their own route segments. Keyed API variants also participate in address generation.
When several fields refer to the same parent resource type, the relationship’s foreign-key identity distinguishes their paths. An address that already identifies a singleton or complete junction can omit a redundant record identifier. Use the generated API reference or URL builders for the final route instead of constructing a parallel naming convention.
Keep the address authoritative on writes
The backend carries contextual parents into the target and write context. A nested write must agree with the parent named by its address. This is separate from whether the caller may perform the operation: both the routing context and operation access rules apply.
A relationship’s context policy determines which related data is loaded, not whether its parent appears in a URL. Keeping those controls separate lets an API offer useful nested addressing without loading whole parent objects in every response.
See the two addresses produced by optional context
Wonder Todos’ generated OpenAPI document contains both collection paths:
POST /api/v1/organizations/{organizationId}/todo-lists/{todoListId}/todos
POST /api/v1/organizations/{organizationId}/todos
The first names the list in the address. The second leaves the list to the submitted fields; organization scope remains in both. These are two entry points to the same resource operation, not separate task-creation implementations.
For example, with real organization and list identifiers substituted into the path, a nested create can omit todoListId from its body:
POST /api/v1/organizations/{organizationId}/todo-lists/{todoListId}/todos
Authorization: Bearer <access-token>
Content-Type: application/json
{
"title": "Prepare the launch",
"recurringType": "one_time"
}
The URL supplies the parent identity. The application’s relationship scenario checks this by creating through the nested path and reading back todoListId. Through the organization-only path, provide the intended todoListId in the body instead. Parent existence, organization membership and operation permissions still need to pass.
Recognize a contradictory parent before retrying
If the nested URL names list A while the body supplies list B, the REST context validator finds different values for the same initiator parameter. The refusal is a validation error: HTTP 400, with the error reference api_call_initiator_parameter_inconsistent. This is the conflict’s identifying contract, not a complete serialized error body.
| Submitted parent information | Meaning |
|---|---|
| Nested URL names A; body omits the list. | Use A from the address. |
| Nested URL names A; body also names A. | Consistent parent information; remaining checks still apply. |
| Nested URL names A; body names B. | Refuse inconsistent context before creating the record. |
| Organization-only URL; body names A. | Resolve and validate A from the body. |
Correct the address or payload so they express one intended parent. Do not retry the same contradictory request or treat the failure as a transient database conflict. The repository’s authoritative-context filter also refuses contradictory scope values; choosing a nested address never replaces authorization.