docs: Update architecture documentation with new handlers

This commit is contained in:
Joachim Van Herwegen 2024-09-12 09:10:18 +02:00
parent 4bea9e3061
commit ee2be9409f
7 changed files with 28 additions and 23 deletions

View File

@ -6,6 +6,8 @@ These are described here.
## Handlers ## Handlers
A very important building block that gets reused in many places is the `AsyncHandler`. A very important building block that gets reused in many places is the `AsyncHandler`.
This interface is extended from the
[asynchronous-handlers](https://www.npmjs.com/package/asynchronous-handlers) library.
The idea is that a handler has 2 important functions. The idea is that a handler has 2 important functions.
`canHandle` determines if this class is capable of correctly handling the request, `canHandle` determines if this class is capable of correctly handling the request,
and throws an error if it can not. and throws an error if it can not.
@ -16,9 +18,9 @@ If an error gets thrown here it means there is an issue with the input.
For example, if the input data claims to be JSON-LD but is actually not. For example, if the input data claims to be JSON-LD but is actually not.
The power of using this interface really shines when using certain utility classes. The power of using this interface really shines when using certain utility classes.
The one we use the most is the `WaterfallHandler`, The one we use the most is the `StatusWaterfallHandler`,
which takes as input a list of handlers of the same type. which takes as input a list of handlers of the same type.
The input and output of a `WaterfallHandler` is the same as those of its inputs, The input and output of a `StatusWaterfallHandler` is the same as those of its inputs,
meaning it can be used in the same places. meaning it can be used in the same places.
When doing a `canHandle` call, it will iterate over all its input handlers When doing a `canHandle` call, it will iterate over all its input handlers
to find the first one where the `canHandle` call succeeds, to find the first one where the `canHandle` call succeeds,
@ -27,7 +29,10 @@ This allows us to chain together many handlers that each have their specific nic
such as handler that each support a specific HTTP method (GET/PUT/POST/etc.), such as handler that each support a specific HTTP method (GET/PUT/POST/etc.),
or handlers that only take requests targeting a specific subset of URLs. or handlers that only take requests targeting a specific subset of URLs.
To the parent class it will look like it has a handler that supports all methods, To the parent class it will look like it has a handler that supports all methods,
while in practice it will be a `WaterfallHandler` containing all these separate handlers. while in practice it will be a `StatusWaterfallHandler` containing all these separate handlers.
Note that `StatusWaterfallHandler` is an extension of the `WaterfallHandler` class
from the [asynchronous-handlers](https://www.npmjs.com/package/asynchronous-handlers) library.
This version makes sure that in case of an error, a correct HTTP status code will be returned.
Some other utility classes are the `ParallelHandler` that runs all handlers simultaneously, Some other utility classes are the `ParallelHandler` that runs all handlers simultaneously,
and the `SequenceHandler` that runs all of them one after the other. and the `SequenceHandler` that runs all of them one after the other.

View File

@ -24,7 +24,7 @@ The `InteractionHandler` is many handlers chained together as follows:
```mermaid ```mermaid
flowchart TD flowchart TD
HttpHandler("<strong>IdentityProviderHttpHandler</strong><br>IdentityProviderHttpHandler") HttpHandler("<strong>IdentityProviderHttpHandler</strong><br>IdentityProviderHttpHandler")
HttpHandler --> InteractionHandler("<strong>InteractionHandler</strong><br>WaterfallHandler") HttpHandler --> InteractionHandler("<strong>InteractionHandler</strong><br>StatusWaterfallHandler")
InteractionHandler --> InteractionHandlerArgs InteractionHandler --> InteractionHandlerArgs
subgraph InteractionHandlerArgs[" "] subgraph InteractionHandlerArgs[" "]
@ -37,7 +37,7 @@ flowchart TD
VersionHandler --> CookieInteractionHandler("<strong>CookieInteractionHandler</strong><br>CookieInteractionHandler") VersionHandler --> CookieInteractionHandler("<strong>CookieInteractionHandler</strong><br>CookieInteractionHandler")
CookieInteractionHandler --> RootControlHandler("<strong>RootControlHandler</strong><br>ControlHandler") CookieInteractionHandler --> RootControlHandler("<strong>RootControlHandler</strong><br>ControlHandler")
RootControlHandler --> LocationInteractionHandler("<strong>LocationInteractionHandler</strong><br>LocationInteractionHandler") RootControlHandler --> LocationInteractionHandler("<strong>LocationInteractionHandler</strong><br>LocationInteractionHandler")
LocationInteractionHandler --> InteractionRouteHandler("<strong>InteractionRouteHandler</strong><br>WaterfallHandler") LocationInteractionHandler --> InteractionRouteHandler("<strong>InteractionRouteHandler</strong><br>StatusWaterfallHandler")
``` ```
The `HtmlViewHandler` catches all request that request an HTML output. The `HtmlViewHandler` catches all request that request an HTML output.
@ -55,4 +55,4 @@ We'll list and summarize these here:
* `RootControlHandler`: Responsible for adding all the [controls](controls.md) to the output. * `RootControlHandler`: Responsible for adding all the [controls](controls.md) to the output.
Will take as input multiple other control handlers which create the nested values in the `controls` field. Will take as input multiple other control handlers which create the nested values in the `controls` field.
* `LocationInteractionHandler`: Catches redirect errors and converts them to JSON objects with a `location` field. * `LocationInteractionHandler`: Catches redirect errors and converts them to JSON objects with a `location` field.
* `InteractionRouteHandler`: A `WaterfallHandler` containing an entry for every supported API [route](routes.md). * `InteractionRouteHandler`: A `StatusWaterfallHandler` containing an entry for every supported API [route](routes.md).

View File

@ -63,7 +63,7 @@ which allows classes to have different support for GET and POST requests.
```json ```json
{ {
"@id": "urn:solid-server:default:InteractionRouteHandler", "@id": "urn:solid-server:default:InteractionRouteHandler",
"@type": "WaterfallHandler", "@type": "StatusWaterfallHandler",
"handlers": [ "handlers": [
{ "@id": "urn:solid-server:default:AccountWebIdRouter" } { "@id": "urn:solid-server:default:AccountWebIdRouter" }
] ]

View File

@ -10,13 +10,13 @@ flowchart LR
subgraph HttpHandlerArgs[" "] subgraph HttpHandlerArgs[" "]
direction LR direction LR
Middleware("<strong>Middleware</strong><br><i>HttpHandler</i>") Middleware("<strong>Middleware</strong><br><i>HttpHandler</i>")
WaterfallHandler("<br>WaterfallHandler") BaseHttpHandler("<strong>BaseHttpHandler</strong><br>StatusWaterfallHandler")
end end
Middleware --> WaterfallHandler Middleware --> BaseHttpHandler
WaterfallHandler --> WaterfallHandlerArgs BaseHttpHandler --> BaseHttpHandlerArgs
subgraph WaterfallHandlerArgs[" "] subgraph BaseHttpHandlerArgs[" "]
direction TB direction TB
StaticAssetHandler("<strong>StaticAssetHandler</strong><br>StaticAssetHandler") StaticAssetHandler("<strong>StaticAssetHandler</strong><br>StaticAssetHandler")
OidcHandler("<strong>OidcHandler</strong><br><i>HttpHandler</i>") OidcHandler("<strong>OidcHandler</strong><br><i>HttpHandler</i>")
@ -39,7 +39,7 @@ The `HttpHandler` is responsible for handling an incoming HTTP request.
The request will always first go through the `Middleware`, The request will always first go through the `Middleware`,
where certain required headers will be added such as CORS headers. where certain required headers will be added such as CORS headers.
After that it will go through the list in the `WaterfallHandler` After that it will go through the list in the `StatusWaterfallHandler`
to find the first handler that understands the request, to find the first handler that understands the request,
with the `LdpHandler` at the bottom being the catch-all default. with the `LdpHandler` at the bottom being the catch-all default.

View File

@ -47,7 +47,7 @@ To subscribe, a client has to send a specific JSON-LD request to the URL found d
```mermaid ```mermaid
flowchart LR flowchart LR
NotificationTypeHandler("<strong>NotificationTypeHandler</strong><br>WaterfallHandler") NotificationTypeHandler("<strong>NotificationTypeHandler</strong><br>StatusWaterfallHandler")
NotificationTypeHandler --> NotificationTypeHandlerArgs NotificationTypeHandler --> NotificationTypeHandlerArgs
subgraph NotificationTypeHandlerArgs[" "] subgraph NotificationTypeHandlerArgs[" "]
@ -76,7 +76,7 @@ flowchart TB
subgraph ListeningActivityHandlerArgs[" "] subgraph ListeningActivityHandlerArgs[" "]
NotificationChannelStorage("<strong>NotificationChannelStorage</strong><br><i>NotificationChannelStorage</i>") NotificationChannelStorage("<strong>NotificationChannelStorage</strong><br><i>NotificationChannelStorage</i>")
ResourceStore("<strong>ResourceStore</strong><br><i>ActivityEmitter</i>") ResourceStore("<strong>ResourceStore</strong><br><i>ActivityEmitter</i>")
NotificationHandler("<strong>NotificationHandler</strong><br>WaterfallHandler") NotificationHandler("<strong>NotificationHandler</strong><br>StatusWaterfallHandler")
end end
NotificationHandler --> NotificationHandlerArgs NotificationHandler --> NotificationHandlerArgs
@ -93,7 +93,7 @@ The `ListeningActivityHandler` is the class that listens to these events
and makes sure relevant notifications get sent out. and makes sure relevant notifications get sent out.
It will pull the relevant subscriptions from the storage and call the stored `NotificationHandler` for each of time. It will pull the relevant subscriptions from the storage and call the stored `NotificationHandler` for each of time.
For every subscription type, a `NotificationHandler` should be added to the `WaterfallHandler` For every subscription type, a `NotificationHandler` should be added to the `StatusWaterfallHandler`
that handles notifications for the specific type. that handles notifications for the specific type.
## WebSocketChannel2023 ## WebSocketChannel2023

View File

@ -38,12 +38,12 @@ flowchart TD
CredentialsExtractor --> CredentialsExtractorArgs CredentialsExtractor --> CredentialsExtractorArgs
subgraph CredentialsExtractorArgs[" "] subgraph CredentialsExtractorArgs[" "]
WaterfallHandler("<br>WaterfallHandler") StatusWaterfallHandler("<br>StatusWaterfallHandler")
PublicCredentialsExtractor("<br>PublicCredentialsExtractor") PublicCredentialsExtractor("<br>PublicCredentialsExtractor")
end end
WaterfallHandler --> WaterfallHandlerArgs StatusWaterfallHandler --> StatusWaterfallHandlerArgs
subgraph WaterfallHandlerArgs[" "] subgraph StatusWaterfallHandlerArgs[" "]
direction LR direction LR
DPoPWebIdExtractor("<br>DPoPWebIdExtractor") --> BearerWebIdExtractor("<br>BearerWebIdExtractor") DPoPWebIdExtractor("<br>DPoPWebIdExtractor") --> BearerWebIdExtractor("<br>BearerWebIdExtractor")
end end
@ -69,7 +69,7 @@ based on the request contents.
```mermaid ```mermaid
flowchart TD flowchart TD
ModesExtractor("<strong>ModesExtractor</strong><br>IntermediateCreateExtractor") ModesExtractor("<strong>ModesExtractor</strong><br>IntermediateCreateExtractor")
ModesExtractor --> HttpModesExtractor("<strong>HttpModesExtractor</strong><br>WaterfallHandler") ModesExtractor --> HttpModesExtractor("<strong>HttpModesExtractor</strong><br>StatusWaterfallHandler")
HttpModesExtractor --> HttpModesExtractorArgs HttpModesExtractor --> HttpModesExtractorArgs
@ -93,7 +93,7 @@ where the necessary modes depend on the body and the PATCH type.
```mermaid ```mermaid
flowchart TD flowchart TD
PatchModesExtractor("<strong>PatchModesExtractor</strong><br>WaterfallHandler") --> PatchModesExtractorArgs PatchModesExtractor("<strong>PatchModesExtractor</strong><br>StatusWaterfallHandler") --> PatchModesExtractorArgs
subgraph PatchModesExtractorArgs[" "] subgraph PatchModesExtractorArgs[" "]
N3PatchModesExtractor("<br>N3PatchModesExtractor") N3PatchModesExtractor("<br>N3PatchModesExtractor")
SparqlUpdateModesExtractor("<br>SparqlUpdateModesExtractor") SparqlUpdateModesExtractor("<br>SparqlUpdateModesExtractor")

View File

@ -17,7 +17,7 @@ The architecture is described more in-depth below.
flowchart LR flowchart LR
PatchingStore("<strong>ResourceStore_Patching</strong><br>ResourceStore") PatchingStore("<strong>ResourceStore_Patching</strong><br>ResourceStore")
PatchingStore --> PatchHandler("<strong>PatchHandler</strong><br>RepresentationPatchHandler") PatchingStore --> PatchHandler("<strong>PatchHandler</strong><br>RepresentationPatchHandler")
PatchHandler --> Patchers("<br>WaterfallHandler") PatchHandler --> Patchers("<br>StatusWaterfallHandler")
Patchers --> ConvertingPatcher("<br>ConvertingPatcher") Patchers --> ConvertingPatcher("<br>ConvertingPatcher")
ConvertingPatcher --> RdfPatcher("<strong>RdfPatcher</strong><br>RdfPatcher") ConvertingPatcher --> RdfPatcher("<strong>RdfPatcher</strong><br>RdfPatcher")
``` ```
@ -25,12 +25,12 @@ flowchart LR
```mermaid ```mermaid
flowchart LR flowchart LR
RdfPatcher("<strong>RdfPatcher</strong><br>RdfPatcher") RdfPatcher("<strong>RdfPatcher</strong><br>RdfPatcher")
RdfPatcher --> RDFStore("<strong>PatchHandler_RDFStore</strong><br>WaterfallHandler") RdfPatcher --> RDFStore("<strong>PatchHandler_RDFStore</strong><br>StatusWaterfallHandler")
RDFStore --> RDFStoreArgs RDFStore --> RDFStoreArgs
subgraph RDFStoreArgs[" "] subgraph RDFStoreArgs[" "]
Immutable("<strong>PatchHandler_ImmutableMetadata</strong><br>ImmutableMetadataPatcher") Immutable("<strong>PatchHandler_ImmutableMetadata</strong><br>ImmutableMetadataPatcher")
RDF("<strong>PatchHandler_RDF</strong><br>WaterfallHandler") RDF("<strong>PatchHandler_RDF</strong><br>StatusWaterfallHandler")
Immutable --> RDF Immutable --> RDF
end end