Skip to content

feat(assets): the typed /assets service - #136

Merged
olavgg merged 1 commit into
mainfrom
feat/assets-service
Sep 18, 2026
Merged

olavgg merged 1 commit into
mainfrom
feat/assets-service

Conversation

@JosteinGj

Copy link
Copy Markdown
Contributor

The api grew a typed /assets family — the last node type without one. Every call is the shared /resources pipeline with the ASSET discriminator pinned server-side, so the two paths cannot drift apart on ACLs, naming policy or status codes. What differs is the shape that comes back: Asset rather than the polymorphic Node, so geolocation and is_root are reachable without a match.

AssetsService covers the whole surface — create, get_by_id, by_ids, list, filter, search, update, delete — in the async client, the blocking mirror and the Python bindings (sync and async).

filter and search reuse ResourceFilterForm and SearchAndFilterForm<ResourceFilter> rather than minting a second Rust spelling of one wire shape: the api declares the same Java types on both endpoint families. A nodeType in the body is replaced with ["asset"], not merged — entries OR together, so merging would widen a request to /assets into a mixed query. The Python filter therefore has no node_type keyword at all; offering a parameter the server silently discards is worse than omitting it.

Behaviours worth knowing, each pinned by a test:

  • A 404 from get_by_id does not mean the id is free. A node of another type, and an asset you may not read, are both reported as missing.
  • Unlike /resources/create, the caller never sets the ASSET label — the endpoint deserializes into the api's Asset, whose constructor forces it in.
  • delete answers 204 with no body, so the wrapper is always empty.
  • update echoes a typed Node, and geolocation is the one update field that means anything on exactly one node type.

PyAsset already existed in the bindings' nodes.rs — it is what PyNode dispatches an ASSET row to — so this adds the service pair only.

The api grew a typed `/assets` family — the last node type without one. Every
call is the shared `/resources` pipeline with the `ASSET` discriminator pinned
server-side, so the two paths cannot drift apart on ACLs, naming policy or
status codes. What differs is the shape that comes back: `Asset` rather than the
polymorphic `Node`, so `geolocation` and `is_root` are reachable without a match.

`AssetsService` covers the whole surface — create, get_by_id, by_ids, list,
filter, search, update, delete — in the async client, the blocking mirror and
the Python bindings (sync and async).

`filter` and `search` reuse `ResourceFilterForm` and
`SearchAndFilterForm<ResourceFilter>` rather than minting a second Rust spelling
of one wire shape: the api declares the same Java types on both endpoint
families. A `nodeType` in the body is *replaced* with `["asset"]`, not merged —
entries OR together, so merging would widen a request to `/assets` into a mixed
query. The Python `filter` therefore has no `node_type` keyword at all;
offering a parameter the server silently discards is worse than omitting it.

Behaviours worth knowing, each pinned by a test:

- A 404 from `get_by_id` does not mean the id is free. A node of another type,
  and an asset you may not read, are both reported as missing.
- Unlike `/resources/create`, the caller never sets the `ASSET` label — the
  endpoint deserializes into the api's `Asset`, whose constructor forces it in.
- `delete` answers 204 with no body, so the wrapper is always empty.
- `update` echoes a typed `Node`, and `geolocation` is the one update field that
  means anything on exactly one node type.

`PyAsset` already existed in the bindings' `nodes.rs` — it is what `PyNode`
dispatches an `ASSET` row to — so this adds the service pair only.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: jgjesdal <jostein@intellistream.ai>
@JosteinGj
JosteinGj requested a review from olavgg September 18, 2026 12:50
@olavgg
olavgg merged commit d4eb4d7 into main Sep 18, 2026
18 checks passed
@olavgg
olavgg deleted the feat/assets-service branch September 18, 2026 14:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants