Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
79f3fa1
add Type Index text
ebremer Mar 30, 2026
88e4be3
make clarifications for fields
ebremer Apr 2, 2026
926018d
clean up text
ebremer Apr 2, 2026
f5e57d1
reworked. location removed from [typeIndexService]. Containers or
ebremer Apr 2, 2026
a0f9e0a
remove filter from [typeIndexService]
ebremer Apr 2, 2026
ad22e84
remove POST in [typeIndexService]
ebremer Apr 2, 2026
67adbe2
remove type filter in [typeIndexService]
ebremer Apr 2, 2026
353e5e0
clairify text
ebremer Apr 2, 2026
8e3413f
remove uuencoding on examples for readability
ebremer Apr 2, 2026
5c0f86f
remove property filter
ebremer Apr 3, 2026
b862890
clarify text
ebremer Apr 3, 2026
a9c5504
soften language on how types are populated into the index
ebremer Apr 15, 2026
f551b6a
reverse order
ebremer Apr 15, 2026
8859fd0
fix storage description for typeSearch and typeIndex
ebremer Apr 15, 2026
5c115d6
formatting
ebremer Apr 15, 2026
bef5eb6
change section header
ebremer Apr 16, 2026
a2094bc
fix typos and parenthesis in wrong place
ebremer May 9, 2026
57f09bd
fix case
ebremer May 15, 2026
a1bd019
case fixes.
ebremer May 15, 2026
f50737b
match pattern of DataSharingService and NotificationService examples
ebremer May 17, 2026
8ece2bc
additional
ebremer May 19, 2026
15e14f9
tighten text
ebremer May 19, 2026
b238a0f
correct type
ebremer May 19, 2026
ea9256c
trim text
ebremer May 19, 2026
bf3f7d7
redundant and confusing
ebremer May 19, 2026
cb1f713
clarify what totalitems actually counts
ebremer May 19, 2026
1f2e3e5
redundant
ebremer May 19, 2026
09e81db
fix examples
ebremer May 29, 2026
3dd27e9
change classes to id instead of type
ebremer May 29, 2026
60b7f28
fix container examples in search results
ebremer May 29, 2026
d50a893
remove manditory status
ebremer May 29, 2026
d8fc1bb
Merge branch 'main' into typeIndex
ebremer May 29, 2026
8ab1e0e
remove hard-coded numbering
ebremer Jun 1, 2026
bd40794
change MUST NOT to MAY to allow servers to extend
ebremer Jun 1, 2026
bea808e
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
4fb82f6
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
542aebf
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
f47a7b2
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
4f11f77
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
5c86e6f
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
a551431
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
5897fc7
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
1f5bf45
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
87eb9ff
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
69797ca
Update lws10-core/Discovery.html
ebremer Jun 8, 2026
a61f22a
Merge branch 'main' into typeIndex
ebremer Jun 12, 2026
573b48a
move Search and Type Index Services into separate document
ebremer Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 231 additions & 0 deletions lws10-core/Discovery.html
Original file line number Diff line number Diff line change
Expand Up @@ -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>

Copy link
Copy Markdown
Member

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.

<p>Supports query parameters (all optional): <code>?type=&lt;URI&gt;</code> (repeatable, AND), <code>?filter[&lt;propURI&gt;]=&lt;value&gt;</code> (repeatable, AND), <code>?fields=type,default,location</code>.</p>
<p class="note">Clients MUST URL-encode query parameter keys/values.</p>
Comment thread
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>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.

@gibsonf1 gibsonf1 Mar 31, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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

ticket

@gibsonf1 gibsonf1 Mar 31, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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

@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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The 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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The 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.

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&amp;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&amp;fields=type,default&amp;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&amp;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&amp;page=2"
}
</pre>

<pre class="example" title="Example 6: POST search with filters">
Request
POST /types/search

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POST /search

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean?

Suggested change
POST /types/search
POST /search

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

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POST /search

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean?

Suggested change
POST /types/search
POST /search

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>