-
Notifications
You must be signed in to change notification settings - Fork 7
Initial CRUD with proposed metadata handling #37
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
base: main
Are you sure you want to change the base?
Changes from all commits
b4175c5
987a4fe
e25aa2e
83a4b77
659fd67
327529e
b0bf4dd
41eb2d9
d7bf619
26a06a8
cadf1ca
d3a0845
336e33d
52e0f9b
99edad3
ddb93e6
9c609a4
9d01d26
39c308a
990ebfc
175907a
778cc62
9818a8b
b8e484b
52b1158
0de8a5d
db703ce
49d45ef
5db9ddb
799b1f6
995bcf2
c249772
0bb3e74
47ae4a0
d6285d7
acbb35e
a8b6d19
bb1969e
a210e13
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 |
|---|---|---|
| @@ -1,19 +1,19 @@ | ||
| name: Add pull requests and issues to projects | ||
|
|
||
| on: | ||
| pull_request_target: | ||
| types: | ||
| - opened | ||
| issues: | ||
| types: | ||
| - opened | ||
|
|
||
| jobs: | ||
| add-to-project: | ||
| name: Add PR and issues to project | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/[email protected] | ||
| with: | ||
| project-url: https://github.com/orgs/w3c/projects/153 | ||
| github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} | ||
| name: Add pull requests and issues to projects | ||
| on: | ||
| pull_request_target: | ||
| types: | ||
| - opened | ||
| issues: | ||
| types: | ||
| - opened | ||
| jobs: | ||
| add-to-project: | ||
| name: Add PR and issues to project | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/[email protected] | ||
| with: | ||
| project-url: https://github.com/orgs/w3c/projects/153 | ||
| github-token: ${{ secrets.ADD_TO_PROJECT_PAT }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,3 @@ | ||
| # Code of Conduct | ||
|
|
||
| All documentation, code and communication under this repository are covered by the [W3C Code of Conduct](https://www.w3.org/policies/code-of-conduct/). | ||
| # Code of Conduct | ||
| All documentation, code and communication under this repository are covered by the [W3C Code of Conduct](https://www.w3.org/policies/code-of-conduct/). |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,24 +1,24 @@ | ||
| # Linked Web Storage Working Group | ||
|
|
||
| Contributions to this repository are intended to become part of Recommendation-track documents governed by the | ||
| [W3C Patent Policy](https://www.w3.org/Consortium/Patent-Policy/) and | ||
| [Document License](https://www.w3.org/copyright/document-license/). To make substantive contributions to specifications, you must either participate | ||
| in the relevant W3C Working Group or make a non-member patent licensing commitment. | ||
|
|
||
| If you are not the sole contributor to a contribution (pull request), please identify all | ||
| contributors in the pull request comment. | ||
|
|
||
| To add a contributor (other than yourself, that's automatic), mark them one per line as follows: | ||
|
|
||
| ``` | ||
| +@github_username | ||
| ``` | ||
|
|
||
| If you added a contributor by mistake, you can remove them in a comment with: | ||
|
|
||
| ``` | ||
| -@github_username | ||
| ``` | ||
|
|
||
| If you are making a pull request on behalf of someone else but you had no part in designing the | ||
| feature, you can remove yourself with the above syntax. | ||
| # Linked Web Storage Working Group | ||
| Contributions to this repository are intended to become part of Recommendation-track documents governed by the | ||
| [W3C Patent Policy](https://www.w3.org/Consortium/Patent-Policy/) and | ||
| [Document License](https://www.w3.org/copyright/document-license/). To make substantive contributions to specifications, you must either participate | ||
| in the relevant W3C Working Group or make a non-member patent licensing commitment. | ||
| If you are not the sole contributor to a contribution (pull request), please identify all | ||
| contributors in the pull request comment. | ||
| To add a contributor (other than yourself, that's automatic), mark them one per line as follows: | ||
| ``` | ||
| +@github_username | ||
| ``` | ||
| If you added a contributor by mistake, you can remove them in a comment with: | ||
| ``` | ||
| -@github_username | ||
| ``` | ||
| If you are making a pull request on behalf of someone else but you had no part in designing the | ||
| feature, you can remove yourself with the above syntax. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| All documents in this Repository are licensed by contributors | ||
| under the | ||
| [W3C Document License](https://www.w3.org/copyright/document-license/). | ||
|
|
||
| All documents in this Repository are licensed by contributors | ||
| under the | ||
| [W3C Document License](https://www.w3.org/copyright/document-license/). | ||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,21 @@ | ||||||
| ### Create Resource Operation | ||||||
| The *create resource* operation requests the creation of a new resource on the server. The resource can be a non-container (data) resource or a container (collection) resource. The operation mandates that the server assigns a new identifier within a target container (like creating a new file in a folder); client-specified full identifiers are not supported for creation in this version to ensure server authority over naming and to simplify interactions. | ||||||
|
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. "Client-specified full identifiers are not supported..." This could be interpreted as "a server MUST NOT", which is probably not what is meant here. |
||||||
|
|
||||||
| **Inputs:** | ||||||
| * **Target container identifier:** The identifier of an existing container where the new resource will be created as a member. | ||||||
| * **Resource content:** The content to store in the resource (binary or text). This is optional to allow creation of an empty container or an empty resource. | ||||||
| * **Suggested name:** An optional hint for naming. The server MAY incorporate this if it does not conflict with naming rules or existing resources. | ||||||
| * **Media type:** The MIME media type or format of the content. This helps the server understand how to store and serve the content. It MUST be provided when content is included and MAY be omitted for empty containers. | ||||||
|
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.
Suggested change
If LWS defines a media type for containers (e.g. |
||||||
|
|
||||||
| **Behavior:** | ||||||
| * The server MUST create a new resource as a member of the specified target container, assigning the identifier (potentially incorporating the suggested name). The new resource is then added to the specified container’s member list via metadata updates. | ||||||
|
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. It's unclear what you mean by "via metadata updates" -- is it a separate operation? Would it suffice to just say "The new resource is then added to the specified container's member list"? |
||||||
| * Upon creation, servers MUST generate a metadata resource linked via Link Sets (RFC 9264), including mandatory server-managed fields such as type (https://www.w3.org/ns/lws#Container or https://www.w3.org/ns/lws#DataResource), mediaType (if applicable), ACL reference, and partOf (linking to the target container). User-managed metadata MAY be provided by the client, but server-managed fields MUST NOT be overridden. | ||||||
| * The server **MAY** enforce additional constraints on creation, such as size limits, quota checks, or restrictions on allowed media types. If any such constraint is violated, the server will reject the operation with an appropriate error. | ||||||
| * The creation MUST be atomic, including metadata generation and container membership updates—if any step fails, no new resource or metadata is created (or any partial artifacts are cleaned up). The identifier of the newly created resource **MUST** be returned to the client (so the client knows how to refer to it). | ||||||
|
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.
Suggested change
The statement "no new resource or metadata is created" should suffice here. |
||||||
|
|
||||||
| **Possible Responses:** *(on the abstract operation level, not tied to a specific protocol)* | ||||||
| * **Created:** The operation succeeded in creating a new resource. The response includes the new resource’s identifier and possibly a minimal representation or metadata. | ||||||
| * **Bad Request:** The request was malformed or violated constraints. The resource was not created. | ||||||
| * **Not Permitted:** The client is not authorized to create a resource in the target location. | ||||||
| * **Not Found:** The specified target container does not exist or cannot be found. This could also be treated as a type of Bad Request or Not Permitted, depending on the cause. | ||||||
| * **Unknown Error:** An internal server error occurred, or some unexpected condition prevented the creation. This is a catch-all for failures not covered by more specific errors. The response would indicate that the server failed the operation (and ideally include an error message or code). | ||||||
|
Comment on lines
+16
to
+21
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. Is this an exhaustive list? Could there be other responses? I think it would be good to allow other possible responses. |
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,24 @@ | ||||||
| ### Delete Resource Operation | ||||||
| The [*delete resource*](https://w3c.github.io/lws-protocol/spec/#dfn-deletion) operation removes an existing resource (or, in some cases, an entire container) from the storage. This operation is akin to deleting a file or folder in a file system. Once completed, the target resource is no longer available for read or update, and its identifier becomes invalid (attempts to access it later should report it as not found, unless it is recreated). Deletes MUST be atomic, including the removal of associated metadata resources and updates to containing container memberships. Metadata lifecycles are tied to the primary resource, with automatic deletion upon resource removal. | ||||||
|
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.
Suggested change
"parent container" seems less repetitive than "containing container" |
||||||
|
|
||||||
| **Inputs**: | ||||||
| * **Target identifier:** The identifier of the resource or container to delete. | ||||||
| * **Optional recursive flag:** Applicable if the target is a container. By default, containers must be empty (no members) to be deleted. If the client explicitly indicates a *recursive delete* (where supported), it signals that the server should delete the container and all of its contents including any sub-containers (akin to `rm -r` on Unix-like OS). This flag must be used with care to avoid accidental mass deletion. | ||||||
| * **Optional concurrency check:** An optional condition to avoid conflicting deletes. This could be an expected version tag or token (for example, a last-known version number or ETag that the client has). Servers MUST support optional concurrency controls failing with Precondition Failed if the resource has changed since the client's last read. | ||||||
|
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.
It is odd to say that an optional feature is required. I believe what you mean is that, if a concurrency control token is provided, any error response MUST be a certain type. Here, I'd be a bit careful, since there could be other errors that happen first, such as an invalid access token or a "Too May Requests" type of error. I would be inclined to be a bit less prescriptive about error codes, though we do want to provide guidance to server implementers. |
||||||
|
|
||||||
| **Behavior:** | ||||||
| * If the target is a **non-container resource** (a single item), the server will remove that resource from storage. This includes deleting its content and any associated metadata or auxiliary resources. For example, if there are separate metadata files (like access control lists or index entries related to that resource), those MUST also be cleaned up as appropriate. After a successful deletion, any subsequent read or update of that resource by clients should be treated as if the resource has never existed (since it no longer does). | ||||||
|
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.
Does that preclude support of |
||||||
| * If the target is a **container resource** (collection), the server will by default only delete it if it has no members (no child resources). This is to prevent accidental deletion of large sets of data. If the container is not empty (the client attempted to delete a non-empty container without explicitly saying it’s okay to also delete everything inside), the server MUST refuse the operation, signaling a conflict. The client then has the responsibility to either start by deleting the members or use an explicit recursive delete (similar to `rm -r`), if the server supports one. Deletes on containers MUST specify recursive or non-recursive behavior (non-recursive as default), failing if non-empty in non-recursive mode. | ||||||
|
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.
Suggested change
Much of the text in the later part of this paragraph seemed redundant. |
||||||
| * If a **recursive delete** is explicitly requested (and supported by the server), the server will attempt to delete the target container and all resources contained within it, potentially including sub-containers and their contents (i.e., the entire sub-tree of that container). If a recursive delete operation fails partway through, the server is not required to roll back the deletions that have already succeeded; i.e., the operation may result in a partially deleted state. The server SHOULD indicate in its error response which resource caused the failure, if possible. Recursive deletion is OPTIONAL for servers; if not supported, servers MUST reject such requests with an appropriate error. It is a dangerous operation, so it MUST be explicit. Some protocols might require a special header or parameter for this. | ||||||
|
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.
Suggested change
Why is this line needed? If a server doesn't support this feature, shouldn't it be possible for the server to ignore the recursive flag, as is the typical convention in HTTP for non-supported client headers. That is, if a client sends a recursive delete on an empty container to a server that doesn't support recursive delete, there is no need to throw an error. If the server does not support recursive deletes and a client attempts to delete a non-empty container, we already have an error for that. |
||||||
| * Authorization checks: The server must verify that the client has permission to delete the resource (and, if recursive, each contained resource). If not authorized, the server will deny the request; if recursive, the denial might come partway through the process. As with reads, if the client is entirely unauthenticated or not permitted, the server MUST refuse in a way that doesn’t reveal (to outsiders) whether the resource existed at all. Unauthorized deletes MUST not disclose resource existence. | ||||||
|
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.
Suggested change
Isn't this implied by the authorization section? |
||||||
| * Upon successful deletion, the target resource is gone. The server should free up any storage associated with it and update any relevant indexes or containing containers. If the resource had specific metadata (like an ACL entry), that metadata MUST also be removed or invalidated. Deleting a container MUST involve updating its containing container to remove the now-deleted child. | ||||||
|
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.
This seems like it gets into implementation details
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.
Suggested change
I would suggest removing this entire line. Internal details are not relevant for the protocol, and the only MUST statement is already included in the lines above. |
||||||
|
|
||||||
| **Possible Responses:** | ||||||
| * **Deleted:** The resource (or container) was successfully deleted. In a concrete protocol this is usually indicated with a confirmation and no content (for example, HTTP 204 No Content). After this response, the client should consider the identifier no longer valid for use unless it’s recreated. Servers MAY indicate permanent removal. | ||||||
|
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 SHOULD? What is meant by "permanent removal"? Are the last two sentences necessary? |
||||||
| * **Not Found:** The resource does not exist (or is already deleted). The server could not perform any deletion because there was nothing to delete. (Again, for unauthorized requests, the server might also use this response to avoid revealing that the resource existed at all.) | ||||||
| * **Not Permitted:** The client is not allowed to delete the resource. The server refused to perform the deletion. In an HTTP scenario this could be a 403 Forbidden. | ||||||
| * **Conflict:** The target is a container that is not empty, and the client did not request (or the server does not allow) recursive deletion. The server leaves the container and its contents intact, and returns an error indicating that the container has members and cannot be removed as requested. The client would need to handle this by emptying the container or explicitly requesting a recursive delete if supported. | ||||||
| * **Precondition Failed:** A concurrency mismatch occurred. The server rejects the delete without changes. | ||||||
| * **Unknown Error:** The server encountered an unexpected error during the deletion process. The state of the system should remain as before, but the operation failed. The server signals a generic internal error to the client. | ||||||
|
|
||||||
| **Note:** When a server denies access (for read, update, delete, etc.) due to authorization, it should do so in a consistent manner. In many cases, a client not authorized to know of a resource’s existence will just get a **Not Found** response instead of **Not Permitted**, to avoid revealing that the resource is there. This is a security consideration that implementations should follow. | ||||||
|
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 would remove this line from this location. It could go in the security considerations section. |
||||||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
| @@ -0,0 +1,20 @@ | ||||||
| ### Read Resource Operation | ||||||
| The [*read resource*](https://w3c.github.io/lws-protocol/spec/#dfn-retrieval) operation retrieves a [resource representation](https://w3c.github.io/lws-protocol/spec/#dfn-resource-representation) of an existing resource or the contents of a container. In other words, it is used to **fetch or access data** stored in the system. This operation covers both reading non-container resources and listing the members of container resources (folders/collections). All reads MUST interact with associated metadata resources as defined in Section 9.1, ensuring atomicity and inclusion of Link Sets (RFC 9264) for descriptions. | ||||||
|
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. These links should be adjusted.
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.
Suggested change
What do you mean by "ensuring atomicity"? |
||||||
|
|
||||||
| **Inputs:** | ||||||
| * **Target identifier:** The unique identifier of the resource or container to read. | ||||||
| * **Optional parameters:** These may include a *preferred format* for the response and/or a *partial range* specifier. For example, a client can request the resource in a specific format or ask for only a portion of the data (such as a byte range or subset), if the protocol supports it. The client might also indicate if it only wants metadata. For containers, parameters MAY include pagination controls or filters for metadata inclusion. | ||||||
|
|
||||||
| **Behavior:** | ||||||
| * If the target is a **non-container resource**, the server returns the content of that resource. By default, the content is returned in its stored format (for example, the exact bytes of an image, or the text of a text file). If the client provided an acceptable format list, the server SHOULD honor it. If the server has multiple representations of the resource or can convert the resource to the requested format, it may return the resource in that format. Otherwise, if the requested format is not available, the server will respond with an error (indicating the format is not acceptable). | ||||||
|
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.
Suggested change
"If the client provided an acceptable format list ..." isn't that just restating RFC 9110 Section 12.5.1? |
||||||
| * If the target is a **container resource**, the server returns a representation of the container’s contents (a **listing of its member resources**). Instead of raw binary content, a container’s “content” is essentially the collection of references to its children. For containers with large memberships, servers MUST support pagination, returning partial listings with links to subsequent pages. Container listings MUST include metadata for each member, such as resource IDs (MUST), types as an array of system and user-defined (MUST), representations with mediaType and optional sizeInBytes (MUST for DataResources), modified timestamps (SHOULD). Servers SHOULD support JSON-LD framing for container responses, using a normative JSON-LD context and optional informative JSON Schema, with a media type like 'application/ld+json; profile="https://www.w3.org/ns/lws/v1"'. The server may format this listing in a suitable manner. By default, if no specific format is requested, the server might return a human-readable HTML or text listing. If a machine-readable format is requested and supported (for example, JSON, XML, or Turtle for RDF), the server can return the listing in that format. Listings MUST be ACL-aware, filtering based on client permissions to ensure privacy. | ||||||
|
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. Assuming that there will be a dedicated section describing containers, a lot of the details in this section could be moved there. |
||||||
| * The read operation also supports *metadata-only* access. For example, a client might perform a read request that asks for no body (just headers or metadata in HTTP, or an existence check). In such cases the server can respond with just the meta-information (like the fact that the resource exists, its last-modified timestamp, size, etc.) without sending the full content. This is useful for clients to verify existence or check for updates without downloading the entire resource. | ||||||
| * **Authorization checks:** If the client does not have permission to read the target resource or container, the server must refuse the read in a way that does not reveal unauthorized information. Specifically, if a request is unauthorized, the server should respond with an access denial. Depending on the implementation’s security model, it might respond as “Not Permitted” (for an authenticated user who lacks read rights) or even as if the resource does not exist (to an unauthenticated request, so as not to confirm the resource’s existence). In other words, unauthorized reads MUST not disclose resource existence. | ||||||
|
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. This should be moved to the authorization section, if it's not already there. |
||||||
|
|
||||||
| **Possible Responses:** | ||||||
| * **Success:** The operation succeeded. For a non-container resource, the full (or requested range of) content is returned, along with relevant metadata (such as content type, length, and a version tag like an ETag or modification time). For a container, a listing of members (in the default or requested format) is returned. In a protocol like HTTP, a success might be a success with 200 OK and include the representation in the response body. | ||||||
|
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.
Suggested change
It seems redundant to give an example for HTTP here and then later describe the REST binding. |
||||||
| * **Not Found:** The target resource or container does not exist (or is not available to the client). The read operation could not be performed. (Also note, as mentioned, an unauthorized request might also result in a response that looks like a Not Found to avoid information disclosure.) | ||||||
|
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 would avoid the nuances about information disclosure and instead put all of that in a privacy considerations section |
||||||
| * **Not Permitted:** The client’s identity is known but they are not allowed to access this resource. The server refuses to provide the content. In an HTTP binding this could be a 403 Forbidden. No details about the resource should be revealed in the response. | ||||||
| * **Not Acceptable:** The client requested a format or representation that the server cannot provide. The resource exists, but the server could not satisfy the `Accept`/format criteria (for example, the client asked for XML but the resource is an image that can only be served in its binary format). In HTTP this corresponds to 406 Not Acceptable, possibly accompanied by a list of available formats or an explanation. | ||||||
| * **Partial Content:** (If partial range was requested and succeeded, or for paginated container listings.) The server returns a fragment of the resource (with status indicating partial content). This would include appropriate headers indicating the range delivered and total size, or links to subsequent pages for pagination. | ||||||
| * **Unknown Error:** Some internal error occurred while trying to read the resource (e.g., a backend failure). The operation did not succeed, and the server signals a generic error (like HTTP 500 Internal Server Error). | ||||||
|
Comment on lines
+17
to
+20
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. As mentioned above, I'd avoid the HTTP examples if they all get restated in the REST binding 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.
@ebremer - do you know why all of these files are appearing in the diff when there don't seem to be any changes?
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.
For several, it's whitespace. Probably line endings.
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.
I moved different sections into sub folders to avoid having one folder with everything.