-
Notifications
You must be signed in to change notification settings - Fork 12
add Type Index Section #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
79f3fa1
88e4be3
926018d
f5e57d1
a0f9e0a
ad22e84
67adbe2
353e5e0
8e3413f
5c0f86f
b862890
a9c5504
f551b6a
8859fd0
5c115d6
bef5eb6
a2094bc
57f09bd
a1bd019
f50737b
8ece2bc
15e14f9
b238a0f
ea9256c
bf3f7d7
cb1f713
1f2e3e5
09e81db
3dd27e9
60b7f28
d50a893
d8fc1bb
8ab1e0e
bd40794
bea808e
4fb82f6
542aebf
f47a7b2
4f11f77
5c86e6f
a551431
5897fc7
1f5bf45
87eb9ff
69797ca
a61f22a
573b48a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -139,5 +139,236 @@ <h4>Storage Description Representation</h4> | |||||
| } | ||||||
| </pre> | ||||||
| </section> | ||||||
|
|
||||||
| </section> | ||||||
|
|
||||||
| <section id="type-index-service"> | ||||||
| <h3>TypeIndexService</h3> | ||||||
| <p>A server advertising in <code>storageDescription</code>:</p> | ||||||
| <pre class="example" title="TypeIndexService advertised in storage description"> | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "Storage", | ||||||
| "service": [ | ||||||
| { | ||||||
| "type": "TypeIndexService", | ||||||
| "serviceEndpoint": "https://example.org/types/index" | ||||||
| } | ||||||
| ] | ||||||
| } | ||||||
| </pre> | ||||||
| <p>A server that implements this MUST advertise the service in the storage description resource.</p> | ||||||
|
|
||||||
| <section> | ||||||
| <h4>GET [serviceEndpoint]</h4> | ||||||
| <p>Returns <code>application/lws+json</code>:</p> | ||||||
| <pre class="example"> | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "TypeIndex", | ||||||
| "searchEndpoint": "https://example.org/types/search", | ||||||
| "totalItems": 55, | ||||||
| "items": [ | ||||||
| { | ||||||
| "type": "https://schema.org/Person", | ||||||
| "default": "https://example.org/data/people/", | ||||||
| "location": ["https://example.org/data/people/"] | ||||||
| }, | ||||||
| { | ||||||
| "type": "https://schema.org/Event", | ||||||
| "default": "https://example.org/data/events/", | ||||||
| "location": [ | ||||||
| "https://example.org/data/events/", | ||||||
| "https://example.org/data/calendar/"] | ||||||
| } | ||||||
| ], | ||||||
| "next": "..." | ||||||
| } | ||||||
| </pre> | ||||||
| <p><code>searchEndpoint</code> REQUIRED.<br><code>default</code> OPTIONAL.<br><code>location</code> array of container URIs (always an array).</p> | ||||||
| <p>Supports query parameters (all optional): <code>?type=<URI></code> (repeatable, AND), <code>?filter[<propURI>]=<value></code> (repeatable, AND), <code>?fields=type,default,location</code>.</p> | ||||||
| <p class="note">Clients MUST URL-encode query parameter keys/values.</p> | ||||||
|
ebremer marked this conversation as resolved.
Outdated
|
||||||
| <p>Returns paginated TypeIndex following LWS pagination. No other parameters.</p> | ||||||
| </section> | ||||||
|
|
||||||
| <section> | ||||||
| <h4>POST [serviceEndpoint]</h4> | ||||||
| <p>MUST support <code>application/lws+json</code> body:</p> | ||||||
| <pre class="example"> | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1" | ||||||
| } | ||||||
| </pre> | ||||||
| <p>Returns everything in the type index (same as GET).</p> | ||||||
| <p>Optional filters: <code>type</code> array of URIs (AND), top-level property-URI keys = filters (AND).</p> | ||||||
| <p>Returns paginated TypeIndex of matching entries. No other params.</p> | ||||||
| </section> | ||||||
|
|
||||||
| <section> | ||||||
| <h4>GET [searchEndpoint]</h4> | ||||||
| <p>Supports same query params as GET [serviceEndpoint] except <code>fields</code>.</p> | ||||||
| <p>Returns <code>application/lws+json</code>: paginated ContainerPage of matching LWS Resource URIs. No other params.</p> | ||||||
| </section> | ||||||
|
|
||||||
| <section> | ||||||
| <h4>POST [searchEndpoint]</h4> | ||||||
| <p>MUST support <code>application/lws+json</code> body:</p> | ||||||
| <pre class="example"> | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": ["https://schema.org/Person"] | ||||||
| } | ||||||
| </pre> | ||||||
| <p><code>type</code>: array of URIs (AND). Top-level property-URI keys = filters (AND).</p> | ||||||
| <p>Returns paginated ContainerPage of matching LWS Resource URIs. No other parameters.</p> | ||||||
| </section> | ||||||
|
|
||||||
| <section> | ||||||
| <h4>Security</h4> | ||||||
| <p>Servers MUST enforce authorization per access grants. Responses to GET/POST on <code>TypeIndexService</code> or <code>searchEndpoint</code> include only types, defaults, locations, and resource URIs the authenticated client may read (via grants). Unauthorized entries omitted. Grant listing implicitly yields a client-specific type index.</p> | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think there should be some required consistency between Access Grants and type indexes. In SAI access grants also serve as type index which besides type and location also provides information about access modes and in the future can include usage policies. Currently there is no default equivalent but I see a need to incubate this future with focus on UX. As for consistency, Besides public read and indexed resources. For all other protected resources which are not public read and not publicly indexed. Is application expected to check both, access grants where it is the assignee and known type indexes? What if those two diverge? I understand that the intention is to have access grants and type indexes as two independent features but they should still reflect some common source of truth. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It makes no sense to be putting things in containers by type - what if something has more than one type? (Most things do) etc. This is an implementation idea best left to implementations or to clients. To create containers and put things in them, that seems to already be covered by other parts of the spec.. What is not currently possible (solid spec) is search on a storage by type no matter where something is - this is only possible with a server type search. Search is the foundational feature for most apps, so having a simple type search will get a foot in the door to providing what all apps actually need.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @gibsonf1 I'm not sure if your reply is specific to my comment, type index seems to assume some kind of partitioning by type, which is not a new idea https://www.w3.org/TR/void/#class-property-partitions My point was mostly abuout consistency with AuthZ. It also isn't a new idea to use access control artifacts for the target resource(s) location discovery There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
@elf-pavlik My point here is that the "Type Index" is a specific client side implementation of an attempt to do type search - which makes no sense in the LWS server spec. We should have a Type Search spec here instead which has no specifics on how an implementation might do things, as opposed to the case in the Solid Client Type Index implementation spec.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think my other comment could be releavant here. Without references to requirements, and through them to use cases, it may not be clear what this proposal intends to satisfy.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree with @elf-pavlik. The field of search is extremely broad, and without clear reference to requirements, it will be challenging to define a proposal that satisfies the entire WG. My understanding is that the specific requirements are based on a need for basic data discovery (distinct from service or capability discovery). In addition, this needs to be implementable by the widest range of servers in an interoperable way. Furthermore the design needs to draw on prior art so that we don't define something that no one will use. In no way should the type index mechanism interfere with an implementation offering other query endpoints. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The agreed to requirement at the F2F was to limit search to a simple type search. This is far less precarious than trying to spec out a client implementation of a type index to try to simulate type search. And is there any in production server based "type index" anywhere? I think not. |
||||||
| </section> | ||||||
|
|
||||||
| <section> | ||||||
| <h4>Non-Normative Examples</h4> | ||||||
|
|
||||||
| <pre class="example" title="Example 1: GET TypeIndex"> | ||||||
| Request | ||||||
| GET /types/index | ||||||
| Response | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "TypeIndex", | ||||||
| "searchEndpoint": "https://example.org/types/search", | ||||||
| "totalItems": 55, | ||||||
| "items": [ | ||||||
| { | ||||||
| "type": "https://schema.org/Person", | ||||||
| "default": "https://example.org/data/people/", | ||||||
| "location": ["https://example.org/data/people/"] | ||||||
| }, | ||||||
| { | ||||||
| "type": "https://schema.org/Event", | ||||||
| "default": "https://example.org/data/events/", | ||||||
| "location": [ | ||||||
| "https://example.org/data/events/", | ||||||
| "https://example.org/data/calendar/"] | ||||||
| } | ||||||
| ], | ||||||
| "next": "https://example.org/types/index?page=2" | ||||||
| } | ||||||
| </pre> | ||||||
|
|
||||||
| <pre class="example" title="Example 2: GET TypeIndex with filter"> | ||||||
| Request | ||||||
| GET /types/index?type=https%3A%2F%2Fschema.org%2FEvent&fields=type,default | ||||||
| Response | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "TypeIndex", | ||||||
| "searchEndpoint": "https://example.org/types/search", | ||||||
| "totalItems": 8, | ||||||
| "items": [{ "type": "https://schema.org/Event", "default": "https://example.org/data/events/" }], | ||||||
| "next": "https://example.org/types/index?type=https%3A%2F%2Fschema.org%2FEvent&fields=type,default&page=2" | ||||||
| } | ||||||
| </pre> | ||||||
|
|
||||||
| <pre class="example" title="Example 3: POST TypeIndex with filters"> | ||||||
| Request | ||||||
| POST /types/index | ||||||
| Request Body | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": ["https://schema.org/Person"] | ||||||
| } | ||||||
| Response | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "TypeIndex", | ||||||
| "searchEndpoint": "https://example.org/types/search", | ||||||
| "totalItems": 27, | ||||||
| "items": [{ "type": "https://schema.org/Person" }], | ||||||
| "next": "https://example.org/types/index?page=2" | ||||||
| } | ||||||
| </pre> | ||||||
|
|
||||||
| <pre class="example" title="Example 4: Simple GET search"> | ||||||
| Request | ||||||
| GET /types/search?type=https%3A%2F%2Fschema.org%2FPerson | ||||||
| Response | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "ContainerPage", | ||||||
| "totalItems": 27, | ||||||
| "items": [ | ||||||
| "https://example.org/data/person-4872", | ||||||
| "https://example.org/data/person-4873", | ||||||
| "https://example.org/data/person-5882", | ||||||
| "https://example.org/data/person-1877", | ||||||
| "https://example.org/data/person-9341" | ||||||
| ], | ||||||
| "next": "https://example.org/types/search?type=https%3A%2F%2Fschema.org%2FPerson&page=2" | ||||||
| } | ||||||
| </pre> | ||||||
|
|
||||||
| <pre class="example" title="Example 5: GET with filter"> | ||||||
| Request | ||||||
| GET /types/search?filter[https://schema.org/location]=https://example.org/venue | ||||||
| Response | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "ContainerPage", | ||||||
| "totalItems": 4, | ||||||
| "items": [ | ||||||
| "https://example.org/data/event-123", | ||||||
| "https://example.org/data/event-456" | ||||||
| ], | ||||||
| "next": "https://example.org/types/search?filter[https%3A%2F%2Fschema.org%2Flocation]=https%3A%2F%2Fexample.org%2Fvenue&page=2" | ||||||
| } | ||||||
| </pre> | ||||||
|
|
||||||
| <pre class="example" title="Example 6: POST search with filters"> | ||||||
| Request | ||||||
| POST /types/search | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. POST /search
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean?
Suggested change
|
||||||
| Request Body | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": ["https://schema.org/Person"], | ||||||
| "https://schema.org/worksFor": "https://example.org/companies/acme-inc" | ||||||
| } | ||||||
| Response | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "ContainerPage", | ||||||
| "totalItems": 3, | ||||||
| "items": [ | ||||||
| "https://example.org/data/person-4872", | ||||||
| "https://example.org/data/person-9341", | ||||||
| "https://example.org/data/person-1123" | ||||||
| ] | ||||||
| } | ||||||
| </pre> | ||||||
|
|
||||||
| <pre class="example" title="Example 7: POST with multiple filters"> | ||||||
| Request | ||||||
| POST /types/search | ||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. POST /search
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you mean?
Suggested change
|
||||||
| Request Body | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": ["https://schema.org/Event"], | ||||||
| "https://schema.org/location": "https://example.org/venue" | ||||||
| } | ||||||
| Response | ||||||
| { | ||||||
| "@context": "https://www.w3.org/ns/lws/v1", | ||||||
| "type": "ContainerPage", | ||||||
| "totalItems": 2, | ||||||
| "items": [ | ||||||
| "https://example.org/data/event-8821", | ||||||
| "https://example.org/data/event-9014" | ||||||
| ], | ||||||
| "next": "https://example.org/types/search?page=2" | ||||||
| } | ||||||
| </pre> | ||||||
| </section> | ||||||
| </section> | ||||||
|
|
||||||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Which use cases and requirements the default property intends to address?
I understand that it intends to indicate a default container for given storage. Are there any restrictions on how many default containers for given type can be indicated in a storage, I would expect just one.
When user has multiple storages, if application has access to discover indexes for given type across some of those storages, there still can be a friction with identifying default of which storage should be used. I think the design of default needs to be evaluated against use cases and requirements it intends to address.