Skip to content

API Scenario Checklist

Use this matrix as a contract checklist for each application resource. The linked guides contain request syntax, controller setup, and response examples. Not every action belongs on every resource; a denied/unpublished capability is an intentional result when your API does not offer it.

Reads And Inputs

Scenario Request/input Expected result
List find?order=id asc 200, response: true, view.data list
Empty list Valid filter matching no rows 200, empty data
Detail find-first?id=1 200, one data object
Missing/hidden detail Unknown or unauthorized ID 404; no record data
Unsaved defaults new 200, unsaved exposed model; no insert
Body fields POST/PUT/PATCH JSON object Body supplies input; query is not merged
DELETE identity delete?id=1 Query ID used; JSON body is not the normal source
Wrong verb GET on a guarded write action 405, unchanged database
Empty write [] or decoded empty object Empty batch succeeds but writes nothing; reject in app if unwanted

See Requests And Responses.

Query Controls

Scenario Input Expected result
Equality/range/list =, between, in filters Only qualifying IDs
Nested OR AND root with nested array Correct grouped result, not flattened conditions
Search Multiple terms, several allowed fields Every term matches at least one configured field
Unconfigured search No search fields No search condition added
NULL/empty Unary null/empty operators Match SQL NULL/trim semantics explicitly
Negative text Negative contains/like Check NULL and no-related-row cases
Prefix exclusion not like: "prefix%" Excludes prefix; do not rely on the current negative-prefix shorthand
Numeric contains JSON integer versus query string Equality versus text behavior; prefer explicit =
Invalid field shape SQL expression as client field 400
Blocked field/operator Outside allowlist/unsupported operator 403
Page one/two Stable order, limit and offset Expected IDs without relying on incidental DB order
Excessive limit Above configured maximum 400
Empty later page Offset beyond matches 200, empty data; full total remains available

See Filtering.

Writes

Scenario Input Expected result
Create One valid object without identity 201, saved true, mode create
Create with identity create plus id/uuid 400; no unintended update
Update Existing permitted identity 200, saved true, mode update
Update without identity Missing ID 400 InvalidUpdate
Update absent/hidden target Unknown/unauthorized ID 404; no creation
Save without target save with missing/unmatched identity May create; use update for must-exist semantics
Uniqueness/validation Duplicate label/invalid business state 422; messages describe failure
Protected field Client submits owner/tenant/admin field Field not assigned; app may explicitly reject
Batch all pass Valid list 200, every row saved
Batch mixed Valid and invalid rows 207, response false, successful rows persist
Batch all fail Invalid list 422, per-row messages
Invalid batch item Scalar within list InvalidPayloadRow for that position
Delete Visible target 200 with deleted; reload checks actual model deletion behavior
Delete missing Unknown target 404
Restore Deleted target visible to restore policy 200 with restored; normal reads see it again
Reorder Position-capable target 200 with reordered; verify neighbors and grouping
Unsupported behavior Restore/reorder on incompatible model Configuration error; do not publish action

See Writes And Batches.

Relationships

Scenario Input Expected result
Default graph find-with without selector Configured graph and constraints
Selected graph Allowed with path Only selected graph, retaining parent constraints
No graph with=0 Root data without eager loading
Blocked graph Unknown relation 403
Invalid selector with=true 400
Plain read with selector find?with=... Does not implicitly become find-with
Child exposure Loaded child has private columns Only explicitly allowed child fields
Related positive text Child contains term Root with a qualifying child
Related negative text Child does not contain term No qualifying child with the positive term, including no-child roots
Same-child filters Same alias/polarity AND predicates One child satisfies the combined condition
Independent children Different bracketed scopes Separate qualifying children allowed
Nested write Allowed child list Authorized child updates/creates, correct parent link
Cross-parent child ID Direct ownership enforcement enabled Reject; original parent link remains intact
Omitted child Keep-missing default Existing child remains
Replacement-style list Explicit keep-missing false policy Verify removals; never assume patch semantics

See Relationships.

Counts And Files

Scenario Input Expected result
List count count=1 Total ignores pagination but keeps row conditions
No count requested Omitted count No count metadata/query required by the action
Count blocked Disallowed selector 403
Grouped count count?group=status Group rows rather than one scalar
Bucket versus total Joined/multi-bucket query Verify sum versus distinct root total separately
Distinct allowed distinct?field=status Scalar values, selected field, page count
Distinct denied/missing Unknown/no field 400
Aggregate Configured column plus action Correct type/value, no pagination
Empty aggregate No matching values Database/native null/false/result contract handled
Export format Explicit contentType Attachment, no JSON envelope
Export bounds Filters/limit/offset/expose list Only permitted selected rows and fields
Export missing library Optional format without dependency Deployment/configuration failure; install before exposing format
Unknown format Unsupported contentType 400

See Counts, Aggregates, And Exports.

Identity And Operations

Verify valid/invalid login, cookie continuity, token refresh, logout, deleted users, role membership, and cross-tenant denials using Authentication. Repeat relevant reads, aggregates, exports, and writes as different identities.

Verify the WebSocket ping/error protocol and any application-owned subscription/reconnect behavior independently from HTTP. Record the actual status, selected IDs, response fields, and persisted state in application tests.