feat: add search query endpoint with request examples - #34
Conversation
Added a new search endpoint for querying resources with detailed request and response structures, including examples for various search scenarios. Based on the MS Graph Search Api of course: https://learn.microsoft.com/en-us/graph/api/resources/search-api-overview?view=graph-rest-1.0
There was a problem hiding this comment.
Pull request overview
Adds an OpenAPI definition for a new beta search endpoint modeled after Microsoft Graph Search, including request/response schemas and multiple example payloads to document common search scenarios.
Changes:
- Introduces
POST /v1beta1/search/querywith detailed description and request/response examples. - Adds search-related schemas (
searchRequest,searchQuery,searchResponse, aggregation/bucket schemas) undercomponents/schemas. - Wires the new endpoint to the new schemas via
$refto keep the spec structured.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 1 out of 1 changed files in this pull request and generated no new comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
@dschmidt Since the search endpoint returns plain drive items I'm wondering how we would handle the additional information the results are currently being enriched with (see https://github.com/opencloud-eu/opencloud/blob/main/services/webdav/pkg/service/v0/search.go#L150-L263 for the current state). Things like the tags could be derived from the arbitrary metadata (which currently isn't exposed afaict), but do you have an idea how we would handle the |
|
Very good questions, thanks! I assume
Although this introduces user specific data to the driveItem, We could introduce a custom prop like |
|
The thumbnails relationship is already in the spec, it might still need implementation tho 😅 |
|
Aha, I just realized the follow endpoints map to setting the favorite state... so just @libre.graph.following or @libre.graph.user.following on the driveItem? If you agree, I can send another PR for that, to keep this one scoped |
|
#37 👀 |
|
What's also potentially missing: short permissions/allowed actions without loading all shares Not sure how we want to do that? Thoughts? |
we introduced @libre.graph.permissions.roles.allowedValues and @libre.graph.permissions.actions.allowedValues to let the web ui build the sharing dialog. see https://docs.opencloud.eu/docs/dev/server/apis/http/graph/permissions for what that looks like or just monitor your browsers network tab when opening the sharing dialog in the web ui. Let me know if that covers what you have in mind |
Adds an optional, `$select`-gated instance annotation on `driveItem` that carries the list of libre.graph actions the caller is allowed to perform on the item. Mirrors the annotation of the same name on the `/permissions` endpoint so clients (e.g. a sharing dialog in a search/listing UI) can get the effective-actions view inline without a separate round-trip per item. - Adds `@libre.graph.permissions.actions.allowedValues` to the `driveItem` schema, marked read-only and documented as only populated when requested. - Adds a reusable `driveItemSelect` component parameter with a narrow enum, following the same pattern as PR #38 (feat/download-url). When both land, the enum values merge. - Wires the new parameter to `GetDriveItem`. Rationale discussed in #34.
The MS Graph token is opaque and varies by bucket type (hex-encoded for terms, range(...) for ranges, with different quoting rules). Rather than commit to that contract, omit the field and let clients construct filters directly from field + key (or the original range definition).
|
@butonic @aduffeck do we want to hold this back until the additional properties are spec'ed and merged or should we progress here independently? They are not hard to add later and merging this would unblock further work on the search service. edit: Then again, they are "half approved". If we can settle on the |
Adds an optional, `$select`-gated instance annotation on `driveItem` that carries the list of libre.graph actions the caller is allowed to perform on the item. Mirrors the annotation of the same name on the `/permissions` endpoint so clients (e.g. a sharing dialog in a search/listing UI) can get the effective-actions view inline without a separate round-trip per item. - Adds `@libre.graph.permissions.actions.allowedValues` to the `driveItem` schema, marked read-only and documented as only populated when requested. - Adds a reusable `driveItemSelect` component parameter with a narrow enum, following the same pattern as PR #38 (feat/download-url). When both land, the enum values merge. - Wires the new parameter to `GetDriveItem`. Rationale discussed in #34.
|
Implementations for the issues raised above:
I think with those in place we can fully replace the WebDAV search... |
|
I've found more missing properties that WebDAV PROPFIND provides but driveItems don't cover yet. Spec PRs:
Together with the already merged following/tags/allowedValues annotations these cover everything web currently reads from PROPFIND (share indicators, lock state, processing state) afaict |
Adds `subAggregations` as an optional array on both the request (`aggregationOption`) and response (`searchBucket`) sides of the search aggregation spec. Lets callers nest term aggregations, e.g. "group by audio.artist, then by audio.album", evaluated in a single request. Explicit libregraph extension beyond MS Graph. Bleve backend emulates via client-side fold over matched hits; OpenSearch would translate to native composite aggregations.
Adds `metricKind` (sum|min|max) to aggregationOption and mirrors `value` + `metricKind` on searchAggregation. When set, the aggregation returns a scalar rather than a bucket list; `size` and `bucketDefinition` are ignored. Libregraph extension, not present in MS Graph. Composable with subAggregations: a metric appears alongside term sub-aggregations inside a parent bucket's subAggregations list, just like in Elasticsearch. The most common use is "for each term bucket, compute a scalar over a numeric field in that bucket's docs", e.g. sum(audio.duration) per audio.album gives total album runtime. Intentionally omits avg/cardinality: avg needs split (sum, count) transport to merge correctly across shards and lands in a follow-up; cardinality is already derivable from a terms sub-aggregation's bucket count.
Adds `avg` as a permitted value on `aggregationOption.metricKind` and `searchAggregation.metricKind`. Distinct from sum/min/max because an average of two averages isn't mergeable: the backend has to carry (sum, count) internally per bucket and only collapse to the scalar `value` at the outermost merge. Wire shape stays symmetrical with sum/min/max: callers still just read `value` off the response; the (sum, count) bookkeeping is entirely service-side.
Added a new search endpoint for querying resources with detailed request and response structures, including examples for various search scenarios.
Based on the MS Graph Search Api of course:
https://learn.microsoft.com/en-us/graph/api/resources/search-api-overview?view=graph-rest-1.0
I'm also willing to implement that endpoint
Libregraph extensions beyond MS Graph
subAggregationsonaggregationOption/searchBucket: nested aggregations, evaluated in a single requestmetricKind(sum/min/max/avg) onaggregationOption, with a scalarvalueonsearchAggregationinstead of bucketsBoth are marked as libregraph extensions in the schema descriptions.