0005. WebDAV Space Key And Storage Space Mapping¶
Status¶
Accepted
Context¶
This package exposes WebDAV endpoints through the route shape /webdav/{space}/{path?}.
The package must support more than one storage target, but the public URL should not be forced to mirror Laravel disk names or raw filesystem paths directly.
There are several competing concerns:
- the request URL needs a stable routing concept that identifies the intended storage target
- consuming applications may want multiple WebDAV entry points with different disks or roots
- storage configuration must stay internal and replaceable instead of becoming part of the public protocol contract
- per-user scoping must still be applied consistently after the target storage area is selected
If the package uses disk names or concrete root paths directly in the URL contract, several problems appear:
- internal Laravel storage details leak into the public WebDAV surface
- renaming disks or changing root paths becomes a breaking WebDAV URL change
- one route parameter would carry too much meaning by mixing routing, storage config, and user scoping
- the package loses a clear boundary between request routing and storage resolution
The current runtime already separates these concerns:
RequestSpaceKeyResolverresolves the{space}route parameter and falls back towebdav-server.storage.default_spaceDefaultSpaceResolvermaps that resolved key towebdav-server.storage.spaces.{spaceKey}- each configured space provides a
disk, aroot, and an optionalprefix - the final storage root path is built as
{root}[/prefix]/{principal.id}
Decision¶
The package keeps space as an explicit, named routing concept and treats it as a storage selection key rather than a
direct disk name or path.
The architectural rules are:
- the public route stays
/webdav/{space}/{path?} {space}resolves to a logicalspaceKeyspaceKeyis looked up inwebdav-server.storage.spaces- each configured space defines the storage target through
disk,root, and optionalprefix - per-user isolation is applied after the space is resolved by appending
{principal.id}to the configured path
The default implementation therefore maps one public route segment to one configured storage space:
- request URL:
/webdav/default/... - resolved key:
default - config lookup:
webdav-server.storage.spaces.default - resulting storage root:
{root}[/prefix]/{principal.id}on the configured disk
This keeps routing terminology stable while leaving the underlying storage model configurable.
Consequences¶
Positive consequences:
- the public WebDAV contract stays stable even if internal disk names or root paths change
- multiple WebDAV spaces can be configured without exposing raw filesystem configuration details
- request routing and storage resolution remain separate responsibilities
- the package can apply per-user scoping consistently after the storage space is selected
- consuming applications can override
SpaceResolverInterfacewhile keeping the same route-level concept
Trade-offs:
- the package introduces one additional concept (
spaceKey) that users must understand - route configuration and storage configuration must stay aligned
- a missing or invalid space configuration fails at runtime instead of being derivable implicitly from the URL
Rejected alternatives:
- use the route parameter directly as the Laravel disk name
- rejected because it leaks internal storage naming into the external WebDAV contract and weakens config flexibility
- encode the full storage root in the URL
- rejected because it exposes internal structure and couples public URLs to implementation details
- drop the space segment and support only one global storage target
- rejected because it removes an important extension point for multi-space routing and future package growth