mirror of
https://github.com/CommunitySolidServer/CommunitySolidServer.git
synced 2024-10-03 14:55:10 +00:00
feat: Add support for StreamingHTTPChannel2023 notifications
* feat: initial StremingHTTPChannel2023 notifications Co-authored-by: Maciej Samoraj <maciej.samoraj@gmail.com> * test: unit for StremingHTTPChannel2023 notifications Co-authored-by: Maciej Samoraj <maciej.samoraj@gmail.com> * test: integration for StremingHTTPChannel2023 notifications Co-authored-by: Maciej Samoraj <maciej.samoraj@gmail.com> * emit initial notification on streaming http channel * fix linting erros * ensure canceling fetch body in integration tests * extract defaultChannel for topic into util * add documentation * Apply suggestions from code review Co-authored-by: Ted Thibodeau Jr <tthibodeau@openlinksw.com> * only generate notifications when needed Co-authored-by: Maciej Samoraj <maciej.samoraj@gmail.com> * test: set body timeout to pass on node >21 Co-authored-by: Maciej Samoraj <maciej.samoraj@gmail.com> * address review feedback * remove node 21 workaround * add architecture documentation * Apply suggestions from code review Co-authored-by: Joachim Van Herwegen <joachimvh@gmail.com> --------- Co-authored-by: Maciej Samoraj <maciej.samoraj@gmail.com> Co-authored-by: Ted Thibodeau Jr <tthibodeau@openlinksw.com> Co-authored-by: Joachim Van Herwegen <joachimvh@gmail.com>
This commit is contained in:
@@ -184,3 +184,45 @@ are quite similar to those needed for WebSocketChannel2023:
|
||||
* The `WebhookChannel2023Type` class contains all the necessary typing information.
|
||||
* `WebhookEmitter` is the `NotificationEmitter` that sends the request.
|
||||
* `WebhookUnsubscriber` and `WebhookWebId` are additional utility classes to support the spec requirements.
|
||||
|
||||
## StreamingHTTPChannel2023
|
||||
|
||||
Currently, support for [StreamingHTTPChannel2023](https://solid.github.io/notifications/streaming-http-channel-2023)
|
||||
only covers default, pre-established channels made available for every resource. Those channels output `text/turtle`.
|
||||
|
||||
Support for custom, subscription-based channels can be added in the future.
|
||||
|
||||
* For discovery, there is a `StreamingHttpMetadataWriter`, which adds `Link` to every `HTTP` response header
|
||||
using `rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023"`. It links directly to the `receiveFrom`
|
||||
endpoint of the default, pre-established channel for that topic resource.
|
||||
* Requests to `receiveFrom` endpoints are handled by a `StreamingHttpRequestHandler`.
|
||||
* It performs an authorization check.
|
||||
* It creates a new response stream and adds it to the `StreamingHttpMap`, indexed by the topic resource.
|
||||
* It sends an initial notification, similar to notification channels using a `state` feature.
|
||||
* `StreamingHttp2023Emitter` is the `NotificationEmitter` that writes notifications to matching response streams.
|
||||
* `StreamingHttpListeningActivityHandler` is responsible for observing the `MonitoringStore`
|
||||
and emitting notifications when needed.
|
||||
It doesn't use a `NotificationChannelStorage` since the default, pre-established channels are not
|
||||
subscription-based. Instead, it uses a `StreamingHttpMap` to check for active receivers.
|
||||
|
||||
```mermaid
|
||||
flowchart TB
|
||||
StreamingHttpListeningActivityHandler("<strong>StreamingHttpListeningActivityHandler</strong><br>StreamingHttpListeningActivityHandler")
|
||||
StreamingHttpListeningActivityHandler --> StreamingHttpListeningActivityHandlerArgs
|
||||
|
||||
subgraph StreamingHttpListeningActivityHandlerArgs[" "]
|
||||
StreamingHttpMap("<strong>StreamingHttpMap</strong><br><i>StreamingHttpMap</i>")
|
||||
ResourceStore("<strong>ResourceStore</strong><br><i>ActivityEmitter</i>")
|
||||
StreamingHttpNotificationHandler("<strong>StreamingHttpNotificationHandler</strong><br><i>ComposedNotificationHandler</i>")
|
||||
end
|
||||
|
||||
StreamingHttpNotificationHandler --> StreamingHttpNotificationHandlerArgs
|
||||
subgraph StreamingHttpNotificationHandlerArgs[" "]
|
||||
direction TB
|
||||
Generator("<strong>BaseNotificationGenerator</strong>")
|
||||
Serializer("<strong>BaseNotificationSerializer</strong>")
|
||||
Emitter("<strong>StreamingHttp2023Emitter</strong><br><i>StreamingHttp2023Emitter</i>")
|
||||
ETagHandler("<strong>ETagHandler</strong>")
|
||||
|
||||
end
|
||||
```
|
||||
|
||||
@@ -127,6 +127,31 @@ The response would then be something like this:
|
||||
}
|
||||
```
|
||||
|
||||
### Streaming HTTP
|
||||
|
||||
Currently, Streaming HTTP channels are only available as pre-established channels on each resource.
|
||||
This means that subscribing and unsubscribing are not supported, and no subscription services are advertised.
|
||||
Instead, each resource advertises the `receiveFrom` of its pre-established notification channel using HTTP Link header,
|
||||
using `rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023"`.
|
||||
|
||||
For example, this —
|
||||
|
||||
```shell
|
||||
curl --head 'http://localhost:3000/foo/'
|
||||
```
|
||||
|
||||
```http
|
||||
HTTP/1.1 200 OK
|
||||
Link: <http://localhost:3000/.notifications/StreamingHTTPChannel2023/foo/>; rel="http://www.w3.org/ns/solid/terms#updatesViaStreamingHttp2023"
|
||||
```
|
||||
|
||||
It is essential to remember that any HTTP request to that `receiveFrom` endpoint requires the same authorization
|
||||
as a `GET` request on the resource which advertises it.
|
||||
|
||||
Currently, all pre-established Streaming HTTP channels have `Content-Type: text/turtle`.
|
||||
|
||||
Information on how to consume Streaming HTTP responses [is available on MDN](https://developer.mozilla.org/en-US/docs/Web/API/Streams_API/Using_readable_streams#consuming_a_fetch_as_a_stream)
|
||||
|
||||
## Unsubscribing from a notification channel
|
||||
|
||||
!!! note
|
||||
|
||||
Reference in New Issue
Block a user