One document matched: draft-ietf-appsawg-json-patch-07.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd" [
<!ENTITY RFC2119 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2119.xml">
<!ENTITY RFC2616 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.2616.xml">
<!ENTITY RFC4627 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.4627.xml">
<!ENTITY RFC5261 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5261.xml">
<!ENTITY RFC5789 SYSTEM "http://xml.resource.org/public/rfc/bibxml/reference.RFC.5789.xml">
]>
<?xml-stylesheet type='text/xsl' href='rfc2629.xslt' ?>
<?rfc strict="yes" ?>
<?rfc toc="yes"?>
<?rfc tocdepth="4"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes" ?>
<?rfc compact="yes" ?>
<?rfc subcompact="no" ?>
<rfc category="info" docName="draft-ietf-appsawg-json-patch-07" ipr="trust200902">
<front>
<title>JSON Patch</title>
<author fullname="Paul C. Bryan" initials="P." surname="Bryan" role="editor">
<organization>Salesforce.com</organization>
<address>
<phone>+1 604 783 1481</phone>
<email>pbryan@anode.ca</email>
</address>
</author>
<author fullname="Mark Nottingham" initials="M." surname="Nottingham"
role="editor">
<organization>Akamai</organization>
<address>
<email>mnot@mnot.net</email>
</address>
</author>
<date year="2012" />
<area>General</area>
<workgroup>Applications Area Working Group</workgroup>
<keyword>json</keyword>
<keyword>HTTP</keyword>
<keyword>format</keyword>
<keyword>diff</keyword>
<abstract>
<t>JSON Patch defines the media type "application/json-patch", a
JSON document structure for expressing a sequence of operations to
apply to a JSON document.</t>
</abstract>
</front>
<middle>
<section title="Introduction">
<t><xref target="RFC4627">JavaScript Object Notation (JSON)</xref>
is a common format for the exchange and storage of structured
data. <xref target="RFC5789">HTTP PATCH</xref> extends the <xref
target="RFC2616">Hypertext Transfer Protocol (HTTP)</xref> with a
method to perform partial modifications to resources.</t>
<t>JSON Patch is a format (identified by the media type
"application/json-patch") for expressing a sequence of operations
to apply to a target JSON document, suitable for use with the HTTP
PATCH method.</t>
<t>This format is also potentially useful in other cases when it's
necessary to make partial updates to a JSON document.</t>
</section>
<section title="Conventions">
<t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL
NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL"
in this document are to be interpreted as described in <xref
target="RFC2119">RFC 2119</xref>.</t>
<t>See <xref target="Errors"/> for information about handling
errors.</t>
</section>
<section anchor="Structure" title="Document Structure">
<t>A JSON Patch document is a <xref target="RFC4627">JSON</xref>
document that represents an array of objects. Each object
represents a single operation to be applied to the target JSON
document.</t>
<figure><preamble>An example JSON Patch document:</preamble><artwork><![CDATA[
[
{ "op": "test", "path": "/a/b/c", "value": "foo" },
{ "op": "remove", "path": "/a/b/c" },
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] },
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" },
{ "op": "copy", "from": "/a/b/d", "path": "/a/b/e" }
]
]]> </artwork></figure>
<t>Evaluation of a JSON Patch document begins with a target JSON
document. Operations are applied sequentially in the order they
appear in the array. Each operation in the sequence is applied to
the target document; the resulting document becomes the target of
the next operation. Evaluation continues until all operations are
successfully applied, or an error condition is encountered.</t>
</section>
<section title="Operations">
<t>Operation objects MUST have exactly one "op" member, whose
value indicates the operation to perform. Its value MUST be one of
"add", "remove", "replace", "move", "copy" or "test". The
semantics of each is defined below.</t>
<t>Additionally, operation objects MUST have exactly one "path"
member, whose value MUST be a string containing a <xref
target="JSON-Pointer"/> value that references a location within
the target document to perform the operation (the "target
location").</t>
<t>Other members of operation objects MUST be ignored, unless they
are explicitly allowed by the definition of the operation.</t>
<t>Note that the ordering of members in JSON objects is not
significant; therefore, the following operation objects are
equivalent:</t>
<figure><artwork><![CDATA[
{ "op": "add", "path": "/a/b/c", "value": "foo" }
{ "path": "/a/b/c", "op": "add", "value": "foo" }
{ "value": "foo", "path": "/a/b/c", "op": "add" }
]]> </artwork></figure>
<t>Operations are applied to the data structures represented
by a JSON document; i.e., after unescaping takes place.</t>
<section title="add">
<t>The "add" operation adds a new value at the target
location. The operation object MUST contain a "value" member
that specifies the value to be added.</t>
<figure><preamble>For example:</preamble><artwork><![CDATA[
{ "op": "add", "path": "/a/b/c", "value": [ "foo", "bar" ] }
]]> </artwork></figure>
<t>When the operation is applied, the target location MUST
reference one of:
<list style="symbols">
<t>The root of the target document - whereupon the
specified value becomes the entire content of the target
document.</t>
<t>A member to add to an existing object - whereupon the
supplied value is added to that object at the indicated
location. If the member already exists, it is replaced
by the specified value.</t>
<t>An element to add to an existing array - whereupon the
supplied value is added to the array at the indicated
location. Any elements at or above the specified index are
shifted one position to the right. The specified index
MUST NOT be greater than the number of elements in the
array. If the "-" character is used to index the end of
the array, this has the effect of appending the value to
the array.</t>
</list></t>
<t>Note that this operation can, in common use, have a target
location that does not resolve to an existing value, resulting
in the pointer's error handling algorithm being invoked. This
specification defines the error handling algorithm for "add"
pointers to explicitly ignore the error and perform the
operation as specified.</t>
<t>However, if the object or array containing it does not
exist, it is an error.</t>
<t>For example, "add"ing to the path "/a/b" to this
document:</t>
<figure><artwork><![CDATA[
{ "a": { "foo": 1 } }
]]> </artwork></figure>
<t>is not an error, because "a" exists, and "b" will be added
to its value. It is an error in this document:</t>
<figure><artwork><![CDATA[
{ "q": { "bar": 2 } }
]]> </artwork></figure>
<t>because "a" does not exist.</t>
</section>
<section title="remove">
<t>The "remove" operation removes the value at the target
location.</t>
<t>The target location MUST exist for the operation to be
successful.</t>
<figure><preamble>For example:</preamble><artwork><![CDATA[
{ "op": "remove", "path": "/a/b/c" }
]]> </artwork></figure>
<t>If removing an element from an array, any elements above
the specified index are shifted one position to the left.</t>
</section>
<section title="replace">
<t>The "replace" operation replaces the value at the target
location with a new value. The operation object MUST contain a
"value" member that specifies the replacement value.</t>
<t>The target location MUST exist for the operation to be
successful.</t>
<figure><preamble>For example:</preamble><artwork><![CDATA[
{ "op": "replace", "path": "/a/b/c", "value": 42 }
]]> </artwork></figure>
<t>This operation is functionally identical to a
"remove" operation for a value, followed immediately by an
"add" operation at the same location with the replacement
value.</t>
</section>
<section title="move">
<t>The "move" operation removes the value at a specified
location and adds it to the target location.</t>
<t>The operation object MUST contain a "from" member, a string
containing a JSON Pointer value that references the location
in the target document to move the value from.</t>
<t>The "from" location MUST exist for the operation to be
successful.</t>
<figure><preamble>For example:</preamble><artwork><![CDATA[
{ "op": "move", "from": "/a/b/c", "path": "/a/b/d" }
]]> </artwork></figure>
<t>This operation is functionally identical to a
"remove" operation on the "from" location, followed
immediately by an "add" operation at the target location with
the value that was just removed.</t>
<t>The target location MUST NOT be part of the location
defined by "from"; i.e., a location cannot be moved into one
of its children.</t>
</section>
<section title="copy">
<t>The "copy" operation copies the value at a specified
location to the target location.</t>
<t>The operation object MUST contain a "from" member, a string
containing a JSON Pointer value that references the location
in the target document to copy the value from.</t>
<t>The "from" location MUST exist for the operation to be
successful.</t>
<figure><preamble>For example:</preamble><artwork><![CDATA[
{ "op": "copy", "from": "/a/b/c", "path": "/a/b/e" }
]]> </artwork></figure>
<t>This operation is functionally identical to an "add"
operation at the target location using the value specified
in the "from".</t>
</section>
<section title="test">
<t>The "test" operation tests that a value at the target
location is equal to a specified value.</t>
<t>The operation object MUST contain a "value" member that
conveys the value to be compared to that at the target
location.</t>
<t>The target location MUST be equal to the "value" value for
the operation to be considered successful.</t>
<t>Here, "equal" means that the value at the target
location and the value conveyed by "value" are of the same
JSON type, and considered equal by the following rules for
that type:</t>
<t><list style="symbols">
<t>strings: are considered equal if they contain the same
number of Unicode characters and their code points are
position-wise equal.</t>
<t>numbers: are considered equal if their values are
numerically equal.</t>
<t>arrays: are considered equal if they contain the same
number of values, and each value can be considered equal to
the value at the corresponding position in the other
array.</t>
<t>objects: are considered equal if they contain the same
number of members, and each member can be considered equal
to a member in the other object, by comparing their keys
as strings, and values using this list of type-specific
rules.</t>
<t>literals (false, true and null): are considered equal
if they are the same.</t>
</list></t>
<t>Note that this is a logical comparison; e.g., whitespace
between the member values of an array is not significant.</t>
<t>Also, note that ordering of the serialisation of object
members is not significant.</t>
<figure><preamble>For example:</preamble><artwork><![CDATA[
{ "op": "test", "path": "/a/b/c", "value": "foo" }
]]> </artwork></figure>
</section>
</section>
<section anchor="Errors" title="Error Handling">
<t>If a <xref target="RFC2119">RFC2119</xref> requirement is
violated by a JSON Patch document, or if an operation is not
successful, evaluation of the JSON Patch document SHOULD terminate
and application of the entire patch document SHALL NOT be deemed
successful.</t>
<t>See <xref target="RFC5789"/>, Section 2.2 for considerations
regarding handling errors when JSON Patch is used with the HTTP
PATCH method, including suggested status codes to use to indicate
various conditions.</t>
<t>Note that the HTTP PATCH method is atomic, as per
<xref target="RFC5789"/>. Therefore, the following patch
would result in no changes being made to the document at all
(because the "test" operation results in an error).</t>
<figure><artwork><![CDATA[
[
{ "op": "replace", "path": "/a/b/c", "value": 42 },
{ "op": "test", "path": "/a/b/c", "value": "C" }
]
]]> </artwork></figure>
</section>
<section anchor="IANA" title="IANA Considerations">
<t>The Internet media type for a JSON Patch document is
application/json-patch.
<list style="hanging">
<t hangText="Type name:">application</t>
<t hangText="Subtype name:">json-patch</t>
<t hangText="Required parameters:">none</t>
<t hangText="Optional parameters: ">none</t>
<t hangText="Encoding considerations:"> binary</t>
<t hangText="Security considerations:"><vspace />
See Security Considerations in section 7.</t>
<t hangText="Interoperability considerations:">N/A</t>
<t hangText="Published specification:"><vspace />[this memo]</t>
<t hangText="Applications that use this media type:"><vspace />
Applications that manipulate JSON documents.</t>
<t hangText="Additional information:"><list>
<t hangText="Magic number(s):">N/A</t>
<t hangText="File extension(s):">.json-patch</t>
<t hangText="Macintosh file type code(s):">TEXT</t>
</list></t>
<t hangText="Person & email address to contact for further information:">
<vspace />Paul C. Bryan <pbryan@anode.ca></t>
<t hangText="Intended usage:">COMMON</t>
<t hangText="Restrictions on usage:">none</t>
<t hangText="Author:">Paul C. Bryan <pbryan@anode.ca></t>
<t hangText="Change controller:">IETF</t>
</list></t>
</section>
<section anchor="Security" title="Security Considerations">
<t>This specification has the same security considerations as
<xref target="RFC4627">JSON</xref> and <xref
target="JSON-Pointer"/>.</t>
<t>A few older Web browsers can be coerced into loading an
arbitrary JSON document whose root is an array, leading to a
situation where a JSON Patch document containing sensitive
information could be exposed to attackers, even if access is
authenticated. This is known as a Cross-Site Request Forgery
(CSRF) attack <xref target="CSRF"/>.</t>
<t>However, such browsers are not widely used ( estimated to
comprise less than 1% of the market, at the time of writing).
Publishers who are nevertheless concerned about this attack are
advised to avoid making such documents available with HTTP
GET.</t>
</section>
<section title="Acknowledgements">
<t>The following individuals contributed ideas, feedback and
wording to this specification:<list>
<t>Mike Acar, Mike Amundsen, Cyrus Daboo, Paul Davis, Murray S. Kucherawy,
Dean Landolt, Randall Leeds, James Manger, Julian Reschke,
James Snell, Eli Stevens and Henry S. Thompson.</t>
</list></t>
<t>The structure of a JSON Patch document was influenced by the
<xref target="RFC5261">XML Patch document</xref> specification.</t>
</section>
</middle>
<back>
<references title="Normative References">
&RFC2119;
&RFC4627;
<reference anchor="JSON-Pointer">
<front>
<title>JSON Pointer</title>
<author initials="P." surname="Bryan" fullname="Paul C. Bryan">
<organization>ForgeRock</organization>
</author>
<author initials="K." surname="Zyp" fullname="Kris Zyp">
<organization>SitePen (USA)</organization>
</author>
<author initials="M." surname="Nottingham" fullname="Mark Nottingham">
<organization>Akamai</organization>
</author>
<date year="2012" month="November"/>
</front>
<seriesInfo name="Internet-Draft" value="draft-ietf-appsawg-json-pointer-06"/>
<format type="TXT" target="http://www.ietf.org/internet-drafts/draft-ietf-appsawg-json-pointer-06.txt"/>
<format type="HTML" target="http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-06"/>
</reference>
</references>
<references title="Informative References">
&RFC2616;
&RFC5261;
&RFC5789;
<reference anchor="CSRF">
<front>
<title>Robust Defenses for Cross-Site Request Forgery</title>
<author initials="A." surname="Barth" fullname="Adam Barth">
<organization>Stanford University</organization>
</author>
<author initials="C." surname="Jackson" fullname="Collin Jackson">
<organization>Stanford University</organization>
</author>
<author initials="J" surname="Mitchell" fullname="John C. Mitchell">
<organization>Stanford University</organization>
</author>
</front>
<format type="PDF" target="http://seclab.stanford.edu/websec/csrf/csrf.pdf"/>
</reference>
</references>
<section title="Examples">
<section anchor="add-member" title="Adding an Object Member">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": "bar"
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "add", "path": "/baz", "value": "qux" }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"baz": "qux",
"foo": "bar"
}
]]> </artwork>
</figure>
</section>
<section anchor="add-element" title="Adding an Array Element">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": [ "bar", "baz" ]
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "add", "path": "/foo/1", "value": "qux" }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": [ "bar", "qux", "baz" ]
}
]]> </artwork>
</figure>
</section>
<section anchor="remove-member" title="Removing an Object Member">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"baz": "qux",
"foo": "bar"
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "remove", "path": "/baz" }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": "bar"
}
]]> </artwork>
</figure>
</section>
<section anchor="remove-element" title="Removing an Array Element">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": [ "bar", "qux", "baz" ]
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "remove", "path": "/foo/1" }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": [ "bar", "baz" ]
}
]]> </artwork>
</figure>
</section>
<section anchor="replace-value" title="Replacing a Value">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"baz": "qux",
"foo": "bar"
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "replace", "path": "/baz", "value": "boo" }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"baz": "boo",
"foo": "bar"
}
]]> </artwork>
</figure>
</section>
<section anchor="move-value" title="Moving a Value">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": {
"bar": "baz",
"waldo": "fred"
},
"qux": {
"corge": "grault"
}
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "move", "from": "/foo/waldo", "path": "/qux/thud" }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": {
"bar": "baz"
},
"qux": {
"corge": "grault",
"thud": "fred"
}
}
]]> </artwork>
</figure>
</section>
<section anchor="move-element" title="Moving an Array Element">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": [ "all", "grass", "cows", "eat" ]
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "move", "from": "/foo/1", "path": "/foo/3" }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": [ "all", "cows", "eat", "grass" ]
}
]]> </artwork>
</figure>
</section>
<section anchor="test-success" title="Testing a Value: Success">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"baz": "qux",
"foo": [ "a", 2, "c" ]
}
]]> </artwork>
</figure>
<t>A JSON Patch document that will result in successful evaluation:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "test", "path": "/baz", "value": "qux" },
{ "op": "test", "path": "/foo/1", "value": 2 }
]
]]> </artwork>
</figure>
</section>
<section anchor="test-error" title="Testing a Value: Error">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"baz": "qux"
}
]]> </artwork>
</figure>
<t>A JSON Patch document that will result in an error condition:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "test", "path": "/baz", "value": "bar" }
]
]]> </artwork>
</figure>
</section>
<section anchor="test-complex" title="Adding a nested Member Object">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": "bar"
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "add", "path": "/child", "value": { "grandchild": { } } }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": "bar",
"child": {
"grandchild": {
}
}
}
]]> </artwork>
</figure>
</section>
<section anchor="unrecognised-elements" title="Ignoring Unrecognized Elements">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo":"bar"
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "add", "path": "/baz", "value": "qux", "xyz": 123 }
]
]]> </artwork>
</figure>
<t>The resulting JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo":"bar",
"baz":"qux"
}
]]> </artwork>
</figure>
</section>
<section anchor="nonexistant-add" title="Adding to a Non-existant Target">
<t>An example target JSON document:</t>
<figure>
<artwork><![CDATA[
{
"foo": "bar"
}
]]> </artwork>
</figure>
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "add", "path": "/baz/bat", "value": "qux" }
]
]]> </artwork>
</figure>
<t>This JSON Patch document, applied to the target JSON
document above, would result in an error (therefore
not being applied) because the "add" operation's target
location that references neither the root of the document,
nor a member of an existing object, nor a member of an
existing array.</t>
</section>
<section anchor="invalid-patch" title="Invalid JSON Patch Document">
<t>A JSON Patch document:</t>
<figure>
<artwork><![CDATA[
[
{ "op": "add", "path": "/baz", "value": "qux", "op": "remove" }
]
]]> </artwork>
</figure>
<t>This JSON Patch document cannot be treated as an "add"
operation since there is a later "op":"remove" element. A JSON
parser that hides such duplicate element names therefore cannot
be used unless it always exposes only the last element with a
given name (eg "op":"remove" in this example).</t>
</section>
</section>
</back>
</rfc>
| PAFTECH AB 2003-2026 | 2026-04-24 06:43:22 |