This
section
defines
the
four
core
operations
that
a
Linked
Web
Storage
(LWS)
server
MUST
support.
These
operations
manipulate
resources
and
containers
in
a
transport-independent
manner,
focusing
on
semantics
rather
than
implementation
details.
Each
operation
specifies
inputs,
expected
behaviors,
and
possible
responses.
Responses
include
success
indicators,
resource
representations
(where
applicable),
and
error
conditions.
Implementations
MUST
handle
these
operations
atomically
and
consistently,
meaning
each
operation
either
succeeds
completely
or
fails
without
partial
side
effects.
In
case
of
errors,
responses
SHOULD
provide
enough
detail
for
agents
to
understand
the
issue
without
leaking
sensitive
information.
For
each
core
operation
(create,
read,
update,
delete),
we
describe
the
HTTP
method(s)
to
use,
required
headers
or
special
considerations
(including
concurrency
controls
via
ETags,
content
negotiation,
and
pagination
for
container
listings),
and
what
the
server
should
do
and
return.
Standard
HTTP
status
codes
are
used
to
indicate
outcomes
with
additional
mappings
for
scenarios
such
as
quota
exceeded
(507
Insufficient
Storage)
or
precondition
failures
(412
Precondition
Failed).
The
binding
tries
to
adhere
to
HTTP/1.1
and
relevant
RFCs
(such
as
[
RFC7231
]
for
HTTP
semantics,
[
RFC7233
]
for
range
requests,
[
RFC5789
]
for
PATCH,
[
RFC8288
]
for
Web
Linking,
and
[
RFC9264
]
for
Link
Sets)
so
that
it
integrates
naturally
with
web
standards.
Discoverability
is
emphasized
through
mechanisms
like
Link
headers
and
WWW-Authenticate
headers
on
401
responses,
avoiding
hardcoded
URI
locations.
Metadata
integration
is
required
across
operations,
ensuring
atomicity
and
use
of
Link
Sets
for
server-managed
and
user-managed
properties.
Note:
As
all
examples
in
this
specifications,
examples
given
in
this
section
(HTTP
request
and
response
snippets)
are
non-normative
,
meant
to
illustrate
typical
usage.
The
actual
requirements
are
stated
in
the
descriptive
text
and
tables.
Also,
while
this
binding
covers
HTTP
(as
the
initial
target
protocol),
the
LWS
operations
could
in
principle
be
bound
to
other
protocols
in
the
future.
Servers
MUST
support
content
negotiation
for
application/lws+json
,
application/ld+json
,
and
application/json
for
container
manifest
representations
(see
Container
Manifest
Media
Type
).
Servers
MAY
additionally
support
formats
like
Turtle.
The
create
resource
operation
adds
a
new
served
resource
to
an
existing
container
patron
.
This
operation
handles
both
the
creation
of
data
contained
resources
(files)
and
sub-containers.
auxiliary
resources.
Inputs:
-
Target
container:
patron:
The
identifier
of
the
container
patron
where
the
new
resource
will
be
created.
created
either
as
an
auxiliary
member
or
as
a
contained
member
if
the
target
is
a
container.
-
membership
link:
The
link
from
the
new
resource
to
the
target
patron.
If
the
new
resource
is
to
be
a
contained
member
of
the
container
patron,
new
resource
is
linked
to
the
patron
container
via
rel="up"
.
If
the
new
resource
is
to
be
a
auxiliary
member
of
the
patron,
new
resource
is
linked
to
the
patron
via
rel="principal"
,
and
patron
resource
is
linked
to
the
new
resource
via
the
auxiliaryRel
of
the
relation.
-
Identity
hint:
An
optional
suggestion
for
the
new
resource's
identifier.
The
server
may
use
this
hint
but
is
not
required
to.
-
Content:
The
initial
content
and
type
for
the
new
resource.
Behavior:
-
Identity
generation:
The
server
determines
the
final
identifier
(URI)
for
the
new
resource.
If
an
identity
hint
was
provided,
the
server
attempts
to
incorporate
it
while
ensuring
uniqueness
and
validity
within
the
container.
scope
of
the
patron
resource.
If
no
hint
is
provided,
the
server
generates
a
unique
identifier.
-
Container
Patron
membership
update:
The
server
atomically
adds
the
new
resource
to
the
contained/auxiliary
membership
listing
of
the
target
container.
patron
by
updating
its
manifest.
It
uses
the
provided
membership
links
to
determine
the
type
of
membership.
-
Metadata
initialization:
The
server
initializes
system
metadata
for
the
new
resource.
If
the
resource
has
an
associated
metadata
resource
it
is
also
initialized.
Possible
Responses:
-
Created:
The
operation
succeeded.
The
server
returns
the
final
identifier
of
the
newly
created
resource.
-
Target
Not
Found:
The
specified
target
container
does
not
exist.
-
Not
Permitted:
The
client's
identity
is
known,
but
they
do
not
have
permission
to
create
resources
in
this
container.
-
Unknown
Requester:
The
server
does
not
recognize
the
client's
identity
and
requires
authentication.
-
Conflict:
A
resource
with
the
generated
identifier
already
exists,
or
requested
membership
is
not
possible
for
the
target
patron
(like
creating
contained
member
on
non-containers,
or
creating
auxiliary
resource
with
already
occupied
auxiliaryRel,
or
requesting
containment
capability
on
the
auxiliary
resource
to
create,
etc.),
or
there
is
another
state
conflict.
-
Unknown
Error:
An
unexpected
internal
error
occurred.
New
resources
are
created
using
POST
to
a
target
container
patron
resource
URI,
with
the
server
assigning
the
final
identifier.
Clients
MAY
suggest
a
name
via
the
Slug
header.
Clients
MAY
provide
initial
user-managed
metadata
for
the
new
resource
by
including
one
or
more
Link
headers
in
the
POST
request,
following
the
syntax
of
Web
Linking
in
[
RFC8288
].
Server-managed
metadata
MUST
be
generated
automatically
by
the
server
upon
creation
and
MUST
NOT
be
overridden
by
client-provided
links.
Server-managed
auxiliary
resources
MUST
be
generated
automatically
by
the
server
upon
creation
of
a
contained
primary
resource.
On
success,
the
server
MUST
return
the
201
status
code
with
the
new
URI
in
the
Location
header.
The
server
MUST
include
Link
headers
for
key
server-managed
metadata,
including
a
link
to
the
parent
container
(
patron
(via
rel="up"
),
for
contained,
via
rel="principal"
for
auxiliary),
and
a
link
links
to
the
created
resource's
dedicated
linkset
resource
Server-managed
auxiliary
resources
(
rel="linkset";
type="application/linkset+json"
).
Additional
links
SHOULD
include
rel="type"
(indicating
https://www.w3.org/ns/lws#Container
or
,
https://www.w3.org/ns/lws#DataResource
https://www.w3.org/ns/lws#Resource
).
,etc).
The
body
MAY
be
empty
or
include
a
minimal
representation
of
the
resource.
All
metadata
creation
and
linking
MUST
be
atomic
with
the
resource
creation
to
maintain
consistency.
POST
(to
a
container
patron
URI)
–
Create
with
server-assigned
name:
Use
POST
to
add
a
new
resource
inside
to
an
existing
patron
resource,
either
as
an
auxiliary
member
or
contained
member
if
the
target
is
a
container.
The
server
assigns
an
identifier
to
the
resource,
optionally
suggested
via
the
Slug
header.
The
server
MAY
honor
the
Slug
header
if
it
does
not
conflict
with
naming
rules
or
existing
resources.
Clients
indicate
the
type
of
resource
to
create
membership
as
follows:
-
To
create
a
Container
Contained
member
,
the
client
MUST
include
a
Link
header
with
rel="type"
rel="up"
pointing
to
the
Container
type:
Link:
<https://www.w3.org/ns/lws#Container>;
rel="type"
.
target
patron
container.
-
To
create
a
an
DataResource
Auxiliary
member
,
the
client
includes
MUST
include
a
Link
header
with
rel="principal"
pointing
to
the
target
principal
resource.
The
client
MUST
also
include
a
Link
header
with
the
anchor
parameter
set
to
the
target
principal
resource,
rel
value
set
to
the
required
auxiliaryRel,
pointing
to
the
new
resource
content
in
to
create
using
an
empty
URI
reference
<>
.
Clients
indicate
the
request
body
with
containment
capability
of
the
appropriate
contained
member
resource
to
create
as
follows:
-
To
create
a
Container
,
the
client
MUST
include
a
Content-Type
Link
header.
header
with
rel="type"
pointing
to
the
Container
type:
Link:
<https://www.w3.org/ns/lws#Container>;
rel="type"
.
Example
(POST
to
create
a
new
data
leaf
resource):
POST /alice/notes/ HTTP/1.1
Host: example.com
Authorization: Bearer <token>
Content-Type: text/plain
Content-Length: 47
Slug: shoppinglist.txt
Link: </alice/notes/> rel="up"
milk
eggs
bread
butter
apples
orange juice
In
this
example,
the
client
is
posting
to
the
container
/alice/notes/
.
It
provides
text/plain
content
(a
grocery
list)
and
suggests
the
name
shoppinglist.txt
for
the
new
resource.
It
provides
membership
link
with
rel="up"
pointing
to
the
current
container,
requesting
to
be
a
contained
member.
If
/alice/notes/
exists
and
the
client
is
authorized,
the
server
will
create
a
new
DataResource
Resource
and
add
it
to
the
container's
membership.
Example
(Response
to
POST
—
Data
Leaf
Resource):
HTTP/1.1 201 Created
Location: /alice/notes/shoppinglist.txt
Content-Type: text/plain; charset=UTF-8
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/shoppinglist.txt.manifest>; rel="manifest"; type="application/lws+json"
Link: </alice/notes/>; rel="up"
<https://www.w3.org/ns/lws#DataResource>; rel="type"
Link: <https://www.w3.org/ns/lws#Resource>; rel="type"
Content-Length: 0
On
success,
return
201
Created
with
the
new
URI
in
the
Location
header.
The
body
may
be
empty
or
a
minimal
representation.
If
the
target
container
/alice/notes/
does
not
exist,
the
server
MUST
return
a
404
error
status
unless
another
status
code
is
more
appropriate.
Creating
Containers:
To
create
a
new
container,
a
client
uses
POST
to
an
existing
parent
container
with
a
Link
header
indicating
the
Container
type.
type,
and
another
Link
header
indicating
containement
membership.
For
example:
POST /alice/ HTTP/1.1
Host: example.com
Authorization: Bearer <token>
Content-Length: 0
Slug: notes
Link: </alice/> rel="up"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Example
(Response
to
POST
—
container):
HTTP/1.1 201 Created
Location: /alice/notes/
Link: </alice/notes/.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/.manifest>; rel="manifest"; type="application/lws+json"
Link: </alice/>; rel="up"
Link: <https://www.w3.org/ns/lws#Container>; rel="type"
Content-Length: 0
This
creates
a
new
container
at
/alice/notes/
,
and
its
server-managed
auxiliary
resources
like
manifest
and
linkset,
with
server-generated
metadata
including
rel="type"
as
https://www.w3.org/ns/lws#Container
.
Example
(POST
to
create
a
new
auxiliary
member
resource):
POST /alice/notes/shoppinglist.txt HTTP/1.1Host: example.comAuthorization: Bearer <token>Content-Type: text/turtleContent-Length: 47Slug: shoppinglist.txt.aclLink: </alice/notes/shoppinglist.txt>; rel="principal"Link: <>; rel="acl"; anchor="/alice/notes/shoppinglist.txt"# This box contains an authorization graph
# It describes the conditions required for accessing a resource
[] a acp:AccessControlResource ;
acp:resource ex:resourceX ;
acp:accessControl [
a acp:AccessControl ;
acp:apply [
a acp:Policy ;
acp:allow acl:Read ;
acp:anyOf [
a acp:Matcher ;
acp:agent ex:Alice, ex:Bob ;
]
]
] .
In
this
example,
the
client
is
posting
to
the
primary
resource
/alice/notes/shoppinglist.txt
,
to
create
an
acl
auxiliary
resource.
It
provides
text/turtle
content
(an
authorization
graph)
and
suggests
the
name
shoppinglist.txt.acl
for
the
new
resource.
It
provides
membership
link
with
rel="principal"
pointing
to
the
principal
resource,
requesting
to
be
an
auxiliary
member.
It
provides
a
link
from
the
principal
resource
to
the
new
resource
with
the
anchor
parameter
set
to
the
primary
resource
URI
and
the
rel="acl"
,
pointing
to
the
new
resource
to
create
using
an
empty
URI
reference
<>
.
If
/alice/notes/shoppinglist.txt
exists
and
the
client
is
authorized,
the
server
will
create
a
new
Resource
and
add
it
to
the
primary
resource's
auxiliary
membership.
Example
(Response
to
POST
—
Auxiliary
Resource):
HTTP/1.1 201 CreatedLocation: /alice/notes/shoppinglist.txt.aclContent-Type: text/plain; charset=UTF-8Link: </alice/notes/shoppinglist.txt>; rel="principal"Link: <>; rel="acl"; anchor="/alice/notes/shoppinglist.txt"Link: <https://www.w3.org/ns/lws#Resource>; rel="type"Content-Length: 0
On
success,
return
201
Created
with
the
new
URI
in
the
Location
header.
The
body
may
be
empty
or
a
minimal
representation.
If
the
target
primary
resource
/alice/notes/shoppinglist.txt
does
not
exist,
the
server
MUST
return
a
404
error
status
unless
another
status
code
is
more
appropriate.
If
the
target
primary
resource
/alice/notes/shoppinglist.txt
already
has
an
auxiliary
resource
with
auxiliaryRel
acl
,
the
server
MUST
return
a
409
error
status
unless
another
status
code
is
more
appropriate.
Additional
notes
on
Create
(HTTP
binding):
-
POST
is
not
idempotent.
Repeating
it
may
create
duplicates;
clients
SHOULD
avoid
unintentional
retries
or
use
unique
identifiers/checks
to
prevent
this.
-
Metadata
updates
are
atomic;
servers
MUST
ensure
the
linkset
resource
is
and
manifest
resources
are
created
and
populated
with
mandatory
server-managed
fields
before
returning
success.
-
For
discoverability,
servers
SHOULD
include
a
Link
header
with
rel="storageDescription"
on
401
responses
to
guide
clients
without
hardcoded
URIs.
Managing
and
Retrieving
Metadata
(Related
to
Creation):
While
metadata
is
primarily
retrieved
via
read
operations,
it
is
generated
during
creation.
Clients
can
immediately
retrieve
it
post-creation
using
GET
or
HEAD
on
the
new
resource
URI.
Clients
can
use
the
Prefer
header
to
request
inclusion
of
specific
metadata
links
(via
relation
types)
and
attributes.
Retrieves
the
representation
of
an
existing
resource
or
the
listing
of
a
container.
resource.
-
Inputs
:
Target
identifier
and
optional
parameters.
-
Behavior
:
-
For
non-container
resources,
the
The
server
returns
the
resource
content.
-
For
containers,
manifest
resources,
the
server
returns
a
manifest
representation
with
listing
of
its
member
resources
which
MAY
be
filtered
based
on
authorization
.
Listings
must
include
core
metadata
for
each
member.
-
Outcome
:
The
requested
representation
or
a
notification
of
failure.
The
read
resource
operation
requests
a
resource
representation
with
HTTP
GET
requests
(and
HEAD
for
header-only
requests).
The
behavior
differs
depending
on
whether
the
target
URL
is
a
container
or
a
non-container
resource
(DataResource).
Servers
MUST
distinguish
resource
types
via
metadata.
All
responses
MUST
integrate
with
metadata
as
defined
in
Section
8.1,
including
Link
headers
for
key
relations
such
as
rel="linkset"
rel="linkset",
rel="manifest"
,
rel="up"
,
rel="principal"
,
and
rel="type"
.
Servers
MUST
ensure
atomicity
between
the
resource
state
and
its
metadata
during
reads.
GET
(non-container
resource)
–
Retrieve
a
resource's
content:
Send
GET
to
the
resource
URI
for
full
content
(if
authorized).
Respond
with
200
OK,
body
containing
the
data,
and
Content-Type
matching
the
stored
media
type.
Servers
MUST
support
range
requests
per
[
RFC7233
]
for
partial
retrieval.
Responses
MUST
include
an
ETag
header
for
concurrency
control
and
caching.
Example
(GET
a
file):
GET /alice/notes/shoppinglist.txt HTTP/1.1
Authorization: Bearer <token>
Accept: text/plain
This
requests
the
content
of
/alice/notes/shoppinglist.txt
,
indicating
that
the
client
wants
it
in
text
form.
Assuming
the
resource
exists,
is
text,
and
the
client
has
access:
HTTP/1.1 200 OK
Content-Type: text/plain; charset=UTF-8
Content-Length: 34
ETag: "abc123456"
Link: </alice/notes/shoppinglist.txt.meta>; rel="linkset"; type="application/linkset+json"
Link: </alice/notes/>; rel="up"
<https://www.w3.org/ns/lws#DataResource>; rel="type"
Link: <https://www.w3.org/ns/lws#Resource>; rel="type"
milk
cheese
bread
guacamole
soda
chocolate bars
hash
eggs
The
server
returned
the
text
content
(34
bytes
in
total,
as
indicated
by
Content-Length
).
The
content
is
exactly
the
stored
data
in
the
file.
The
ETag:
"abc123456"
is
a
version
identifier
for
caching
or
concurrency
purposes.
The
response
includes
Link
headers
for
metadata
discoverability,
with
mandatory
fields
such
as
up
and
type
.
GET
(container
(manifest
resource)
–
List
Retrieve
a
container's
contents:
resource's
manifest:
When
the
target
URI
corresponds
to
a
container
(determined
via
metadata
type),
manifest
resource,
a
GET
request
returns
a
listing
of
the
container's
members.
The
response
body
is
a
container
manifest
representation
as
defined
in
the
Container
Manifest
Representation
section,
using
the
LWS
container
manifest
media
type.
The
listing
manifest
includes
metadata
for
each
member:
of
contained
auxiliary
members:
resource
identifiers
(
MUST
),
types
(
MUST
),
media
types
(
MUST
for
DataResources),
),
sizes
(
SHOULD
),
and
modification
timestamps
(
SHOULD
).
Example
(GET
a
container):
manifest):
GET /alice/notes/~manifest HTTP/1.1
Authorization: Bearer <token>
application/ld+json
Accept: application/lws+json
Assuming
the
container
principal
resource
and
the
manifest
exists
and
the
client
has
access:
HTTP/1.1 200 OK
Content-Type: application/lws+json
"container-etag-789"
</alice/notes/.meta>; rel="linkset"; type="application/linkset+json"
</alice/>; rel="up"
<https://www.w3.org/ns/lws#Container>; rel="type"
ETag: "manifest-etag-789"
Link: </alice/notes/>; rel="principal";
{
"@context": "https://www.w3.org/ns/lws/v1",
"id": "/alice/notes/",
"type": ["Resource", "Container"],
"totalItems": 2,
"items": [
{
"type": "Resource",
"id": "/alice/notes/shoppinglist.txt",
"mediaType": "text/plain",
"size": 47,
"modified": "2025-11-24T12:00:00Z"
},
{
"type": ["Resource", "http://example.org/customType"],
"id": "/alice/notes/todo.json",
"mediaType": "application/json",
"size": 2048,
"modified": "2025-11-24T13:00:00Z"
}
],
"auxiliaryMap": {
"manifest": {
"id": "/alice/notes/~manifest.json",
"type": ["Manifest", "Resource"],
"mediaType": "application/lws+json",
"modified": "2025-11-24T14:00:00Z",
},
"linkset": {
"id": "/alice/notes/~linkset.json",
"type": ["Linkset", "Resource"],
"mediaType": "application/linkset+json",
"modified": "2025-11-24T14:00:00Z",
},
"acl": {
"id": "/alice/notes/~acl",
"type": ["Resource"],
"mediaType": "text/turtle",
"modified": "2025-12-24T15:00:00Z",
}
}
}
In
this
example,
/alice/notes/
is
a
container.
container,
and
alice/notes/~manifest
is
it's
manifest
auxiliary
resource.
The
response
uses
JSON-LD
with
the
LWS
context,
listing
contained
and
auxiliary
members
with
required
metadata.
Each
item
includes
its
type
,
id
,
mediaType
,
size
,
and
modified
timestamp
as
flat
properties.
In
all
cases,
the
server
MUST
include
the
following
metadata
in
the
response
headers:
an
ETag
(representing
the
listing
version,
which
changes
on
membership
modifications),
and
Link
headers
with
rel="type"
indicating
if
it
is
a
container,
rel="linkset"
and
rel="up"
.
if
it
is
a
contained
resource
and
rel="principal"
if
it
is
an
auxiliary
resource.
HEAD
(any
resource
or
container)
–
Headers/metadata
only:
The
LWS
server
MUST
support
HEAD
[
RFC9110
]
for
both
containers
and
non-containers,
all
resources
in
storage,
returning
the
same
headers
as
GET
(including
ETag,
Content-Type,
Link
for
metadata)
but
without
a
body.
This
enables
metadata
retrieval
without
transferring
content.
Caching
and
Conditional
Requests:
LWS
leverages
HTTP
caching
semantics.
Servers
MUST
support
conditional
requests
via
If-None-Match
(with
ETags)
or
If-Modified-Since
headers.
If
the
resource
or
container
listing
has
not
changed,
respond
with
304
Not
Modified
to
avoid
redundant
transfers.
ETags
MUST
be
provided
in
all
GET/HEAD
responses
for
concurrency
and
caching
support.
Discoverability
and
Authorization:
For
enhanced
discoverability,
servers
SHOULD
include
WWW-Authenticate
headers
on
401
Unauthorized
responses
with
parameters
to
guide
clients
without
hardcoded
URIs.
Metadata
links
SHOULD
be
included
where
applicable.
Modifies
the
state
of
an
existing
[served
resource]
via
full
replacement
or
a
partial
patch.
-
Inputs
:
Target
identifier,
new
content,
and
optional
concurrency
constraints.
-
Behavior
:
The
server
applies
the
changes
atomically.
If
concurrency
constraints
are
provided,
the
update
is
rejected
if
the
resource
has
been
modified
since
it
was
last
read
by
the
requester.
-
Outcome
:
Confirmation
of
the
update
or
a
notification
of
conflict.
The
update
resource
modifies
the
contents
of
an
existing
served
resource
by
a
PUT
request
(to
replace
the
entire
resource)
or
a
PATCH
request
(to
apply
a
partial
modification).
The
client
must
have
write
access
to
the
resource’s
URL
to
perform
these
operations.
Note:
This
section
describes
updating
a
resource's
primary
content.
To
update
its
metadata,
see
Section
9.3.2.
LWS
servers
MUST
handle
PUT
and
PATCH
requests
on
resource
URIs
as
modifications
to
the
resource
content
only,
with
no
default
impact
on
the
associated
linkset.
To
optionally
update
both
content
and
metadata
in
a
single
atomic
operation,
clients
MAY
include
Link
headers
in
the
PUT/PATCH
request
to
the
resource
URI
and
specify
the
preference
'Prefer:
set-linkset'
(as
defined
in
RFC
7240).
In
this
case,
the
server
MUST
interpret
the
provided
Link
headers
as
a
replacement
(for
PUT)
or
partial
update
(for
PATCH)
to
the
linkset,
in
addition
to
applying
the
content
changes.
This
behavior
is
OPTIONAL
for
servers
but,
if
supported,
MUST
be
invoked
explicitly
via
the
Prefer
header
to
prevent
unintentional
metadata
overwrites.
Servers
that
do
not
support
combined
updates
MUST
ignore
the
preference
or
respond
with
501
Not
Implemented.
PUT
(replace
full
resource)
–
Send
PUT
to
the
resource
URI
with
new
full
content
in
the
body
and
matching
Content-Type
(generally
consistent
with
existing
type).
PUT
is
idempotent
for
existing
resources.
For
safety,
include
If-Match
with
current
ETag
(per
Section
7.3
concurrency);
mismatch
yields
412
Precondition
Failed
or
409
Conflict.
Without
checks,
updates
are
unconditional
but
risk
overwriting
concurrent
changes.
If
a
server
supports
Etags
for
a
resource,
it
MUST
reject
unconditional
PUT
requests
that
lack
an
If-Match
header
with
a
428
Precondition
Required
response.
Example
(PUT
to
update
a
resource):
PUT /alice/personalinfo.json HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/json
If-Match: "abc123456"
{
"name": "Alice",
"age": 30,
"city": "New London",
"state": "Connecticut"
}
In
this
example,
the
client
is
updating
an
existing
JSON
resource
at
/alice/personalinfo.json.
It
includes
an
If-Match
header
with
the
ETag
"abc123456"
that
it
got
from
an
earlier
GET
or
HEAD
request.
The
server
will
compare
that
to
the
current
ETag;
if
they
match,
it
proceeds
to
replace
the
content
with
the
JSON
provided.
If
they
don’t
match,
the
server
rejects
the
update
(because
the
resource
was
changed
by
someone
else
in
the
meantime).
Successful
response:
If
the
update
succeeds,
the
server
can
respond
with
200
OK
and
possibly
include
the
updated
representation
or
some
confirmation
(like
the
new
content
or
a
part
of
it).
Alternatively,
the
server
may
respond
with
204
No
Content
to
indicate
success
with
no
body
(especially
common
if
no
further
info
needs
to
be
conveyed).
In
either
case,
the
server
SHOULD
include
a
new
ETag
to
signify
the
new
version,
and
maybe
a
Content-Type
if
a
body
is
returned.
For
example:
HTTP/1.1 204 No Content
ETag: "def789012"
This
tells
the
client
the
update
went
through
and
provides
the
new
ETag
.
If
the
server
chose
to
return
the
updated
content,
it
might
use
200
OK
and
include
the
JSON
in
the
body,
along
with
headers.
-
Error
responses:
If
the
If-Match
did
not
match
(concurrent
modification),
the
server
could
return
412
Precondition
Failed
(meaning
the
precondition
header
failed)
or
409
Conflict
–
our
earlier
abstract
description
used
Conflict
for
concurrency
issues,
and
409
is
a
natural
mapping
for
that
scenario.
If
the
resource
did
not
exist,
a
PUT
meant
as
an
update
will
result
in
404
Not
Found
(unless
the
intent
was
to
create,
but
typically
clients
use
PUT
for
create
only
when
they
are
sure
of
what
they’re
doing,
or
they
use
it
as
upsert
without
If-Match).
If
the
client
is
not
authorized,
403
Forbidden
(or
401
Unauthorized
if
no
valid
credentials
were
provided).
If
the
request
payload
is
not
valid,
400
Bad
Request
.
PATCH
(partial
update)
–
The
HTTP
PATCH
method
[
RFC5789
]
allows
a
client
to
specify
partial
modifications
to
a
resource,
rather
than
sending
the
whole
new
content.
This
is
useful
for
large
resources
where
sending
the
entire
content
would
be
inefficient
if
only
a
small
part
changed,
or
for
concurrent
editing
where
you
want
to
apply
specific
changes.
LWS
server
MUST
minimally
support
JSON
Merge
Patch
(application/merge-patch+json)
as
defined
in
[
RFC7386
].
Update
Primary
Resource
Metadata
(HTTP
PUT
/
PATCH
on
Linkset)
A
primary
resource's
metadata
is
updated
by
modifying
its
corresponding
linkset
auxiliary
resource,
discovered
via
the
Link
header
with
rel="linkset".
Full
Replacement
(PUT):
A
PUT
request
to
the
linkset
URI
with
a
complete
linkset
document
in
the
body
replaces
all
metadata
for
the
resource.
Partial
Update
(PATCH):
A
PATCH
request
to
the
linkset
URI
adds,
removes,
or
modifies
specific
links.
Concurrency
Control
for
Metadata
Because
a
primary
resource's
metadata
can
be
modified
by
multiple
actors,
preventing
concurrent
overwrites
is
critical.
To
ensure
data
integrity,
LWS
servers
and
clients
MUST
implement
optimistic
concurrency
control
using
conditional
requests
[
RFC7232
]
for
all
PUT
and
PATCH
operations
on
a
linkset
resource.
Server
Responsibilities:
A
server
MUST
include
an
Etag
header
in
its
responses
to
GET
and
HEAD
requests
for
a
linkset
resource.
Upon
a
successful
PUT
or
PATCH
on
the
linkset,
the
server
MUST
generate
a
new,
unique
Etag
value
for
the
modified
linkset
and
return
it
in
the
Etag
header
of
the
response.
Client
Responsibilities:
When
modifying
a
linkset
resource,
a
client
MUST
include
an
If-Match
header
containing
the
most
recent
Etag
it
received
for
that
resource.
Processing
Rules:
If
the
If-Match
header
value
does
not
match
the
linkset's
current
Etag,
the
server
MUST
reject
the
request
with
a
412
Precondition
Failed
status
code.
If
the
If-Match
header
is
missing
from
a
PUT
or
PATCH
request
to
a
linkset
URI,
the
server
MUST
reject
the
request
with
a
428
Precondition
Required
status
code
[
RFC6585
].
Example
(PUT
to
replace
a
linkset):
A
client
first
fetches
the
linkset
and
receives
its
ETag.
GET /alice/personalinfo.json.meta HTTP/1.1
Authorization: Bearer <token>
Accept: application/linkset+json
HTTP/1.1 200 OK
Content-Type: application/linkset+json
ETag: "meta-v1"
{
"linkset": [
{
"anchor": "/alice/personalinfo.json",
"describedby": [ { "href": "/schemas/personal-info.json" } ]
}
]
}
The
client
now
wants
to
add
a
license.
It
constructs
a
new,
complete
linkset
document
and
sends
a
PUT
request
with
the
If-Match
header.
PUT /alice/personalinfo.json.meta HTTP/1.1
Authorization: Bearer <token>
Content-Type: application/linkset+json
If-Match: "meta-v1"
{
"linkset": [
{
"anchor": "/alice/personalinfo.json",
"describedby": [ { "href": "/schemas/personal-info.json" } ],
"license": [ { "href": "https://creativecommons.org/licenses/by/4.0/" } ]
}
]
}
If
successful,
the
server
responds
with
success
and
the
new
ETag.
HTTP/1.1 204 No Content
ETag: "meta-v2"
Summary
of
Update
Rules
If
you
want
to
change
only
the
content
of
a
resource
→
PUT/PATCH
the
resource
itself.
If
you
want
to
change
only
the
links
(metadata)
of
a
resource
→
PUT/PATCH
the
resource’s
associated
linkset
resource.
If
you
want
to
change
both
content
and
links
→
PUT/PATCH
the
resource
itself,
including
the
appropriate
Link
headers
AND
'Prefer:
set-linkset'.
Setting
both
is
off
by
default.
Permanently
removes
a
resource
and
its
associated
metadata.
auxiliary
resources.
-
Inputs
:
Target
identifier,
an
optional
recursive
flag
(for
containers),
and
optional
concurrency
constraints.
-
Behavior
:
-
For
non-container
primary
resources,
the
server
removes
the
content,
metadata,
all
its
auxiliary
resources,
and
updates
the
parent
container's
containment
membership.
-
For
containers,
the
server
typically
requires
the
container
to
be
empty
unless
a
recursive
delete
is
explicitly
requested
and
supported.
-
For
auxiliary
resources,
the
server
removes
the
content,
metadata,
and
updates
the
principal
resource's
auxiliary
membership.
-
Outcome
:
Confirmation
of
removal
or
a
notification
of
failure.
The
delete
resource
operation
is
implemented
using
the
HTTP
DELETE
method,
as
defined
in
the
abstract
operation
above.
This
section
specifies
the
HTTP
bindings
for
inputs,
behaviors,
and
responses.
The
DELETE
request
targets
the
URI
of
the
resource
or
container
to
remove.
Clients
MAY
include
an
If-Match
header
with
an
ETag
for
concurrency
checks.
Deletion
and
Containment:
When
a
contained
resource
is
deleted,
the
server
MUST
atomically
remove
it
from
its
parent
container's
container
manifest's
items
containedItems
list.
The
parent
container's
container
manifest's
totalItems
totalContainedItems
count
and
ETag
MUST
be
updated
accordingly.
When
an
auxiliary
resource
is
deleted,
the
server
MUST
atomically
remove
the
corresponding
entry
from
its
principal
resource
manifest's
auxiliaryMap
list,
and
MUST
remove
the
auxiliarity
link
from
the
principal
resource's
metadata
linkset.
ETags
of
the
manifest
and
linkset
resources
of
the
principal
resource
MUST
be
updated
accordingly.
For
non-container
all
resources,
the
server
removes
the
resource
content,
content.
For
all
primary
resources,
the
server
removes
its
associated
metadata
(linkset),
and
the
containment
reference
in
the
parent
container.
auxiliary
resources.
For
container
resources,
the
server
defaults
to
non-recursive
deletion.
If
the
container
is
not
empty
and
recursion
is
not
requested,
the
server
MUST
reject
the
request
with
409
Conflict.
Servers
MAY
support
recursive
deletion
of
all
contained
resources
within
the
container
that
is
being
deleted.
Clients
MUST
use
the
Depth:
infinity
header
to
request
for
a
recursive
delete,
as
defined
in
[
RFC4918
].
On
success,
the
server
MUST
respond
with
204
No
Content.
Servers
SHOULD
support
conditional
requests,
as
defined
in
[
RFC9110
].
If
the
client
lacks
authorization,
the
server
MUST
return
403
Forbidden
(if
the
client's
identity
is
known
but
permissions
are
insufficient)
or
401
Unauthorized
(if
no
valid
authentication
is
provided).
In
cases
where
revealing
resource
existence
poses
a
security
risk,
the
server
MAY
return
404
Not
Found
instead.
Example
(DELETE
a
non-container
contained
resource):
DELETE /alice/notes/shoppinglist.txt HTTP/1.1
Authorization: Bearer <token>
If-Match: "abc123456"
Assuming
the
ETag
matches
and
the
client
is
authorized,
the
server
deletes
the
resource,
its
metadata,
auxiliary
resources,
and
removes
it
from
the
parent
container
/alice/notes/
by
updating
its
manifest
atomically:
HTTP/1.1 204 No Content
Example
(DELETE
a
non-empty
container
without
recursion):
DELETE /alice/notes/ HTTP/1.1
Authorization: Bearer <token>
Assuming
/alice/notes/
contains
resources,
the
server
refuses
the
deletion:
HTTP/1.1 409 Conflict
Content-Type: text/plain
Cannot delete container /alice/notes/ - container is not empty.
Example
(DELETE
a
container
with
recursion,
if
supported):
DELETE /alice/notes/ HTTP/1.1
Authorization: Bearer <token>
Depth: infinity
Assuming
the
server
supports
recursion
and
the
client
has
permissions
for
all
contents,
the
server
deletes
the
container
,
its
auxiliary
resources,
and
its
descendants
atomically:
HTTP/1.1 204 No Content
Example
(DELETE
a
non-server-managed
auxiliary
resource):
DELETE /alice/notes/~acl HTTP/1.1Authorization: Bearer <token>If-Match: "abc123456"
Assuming
the
ETag
matches
and
the
client
is
authorized,
the
server
deletes
the
auxiliary
resource
and
removes
it
from
the
principal
resource
/alice/notes/
by
updating
its
manifest
atomically:
HTTP/1.1 204 No Content
This
table
maps
generic
LWS
responses
(from
Section
8)
to
HTTP
status
codes
and
payloads
for
consistency,
incorporating
specific
scenarios
such
as
pagination,
concurrency
controls,
quota
constraints,
and
metadata
integration:
|
LWS
response
|
HTTP
status
code
|
HTTP
payload
|
|
Success
(read
or
update,
returning
data)
|
200
OK
|
Resource
representation
in
the
response
body
(for
GET
or
if
PUT/PATCH
returns
content),
along
with
relevant
headers
(Content-Type,
ETag,
Link
for
metadata
such
as
rel="linkset",
rel="up").
For
container
listings,
manifest
representations,
include
JSON-LD
with
normative
context
and
member
metadata
(IDs,
types,
sizes,
timestamps).
|
|
Created
(new
resource)
|
201
Created
|
Typically
no
response
body
(or
a
minimal
representation
of
the
new
resource).
The
Location
header
is
set
to
the
new
resource’s
URI.
Headers
like
ETag
MUST
be
included
for
concurrency;
Link
headers
for
server-managed
metadata.
|
|
Deleted
(no
content
to
return)
|
204
No
Content
|
No
response
body.
Indicates
the
resource
was
deleted
or
the
request
succeeded
and
there’s
nothing
else
to
say.
Servers
MAY
use
410
Gone
for
permanent
deletions.
|
|
Bad
Request
(invalid
input
or
constraints)
|
400
Bad
Request
|
Error
details
explaining
what
was
wrong.
Servers
SHOULD
use
the
standard
format
defined
in
[
RFC9457
]
for
structured
error
responses,
such
as
a
JSON
object
with
fields
like
"type",
"title",
"status",
"detail",
and
"instance".
|