diff --git a/stream/src/main/scala/org/apache/pekko/stream/impl/JsonObjectParser.scala b/stream/src/main/scala/org/apache/pekko/stream/impl/JsonObjectParser.scala index 369835419c..f3431cb909 100644 --- a/stream/src/main/scala/org/apache/pekko/stream/impl/JsonObjectParser.scala +++ b/stream/src/main/scala/org/apache/pekko/stream/impl/JsonObjectParser.scala @@ -52,8 +52,8 @@ import pekko.util.ByteString * INTERNAL API: Use [[pekko.stream.scaladsl.JsonFraming]] instead. * * **Mutable** framing implementation that given any number of [[pekko.util.ByteString]] chunks, can emit JSON objects contained within them. - * Typically JSON objects are separated by new-lines or commas, however a top-level JSON Array can also be understood and chunked up - * into valid JSON objects by this framing implementation. + * Typically JSON objects are separated by newlines or commas. A top-level JSON array is supported as a container + * of objects, but top-level non-object values are not supported. * * Leading whitespace between elements will be trimmed. */ @@ -90,7 +90,8 @@ import pekko.util.ByteString /** * Attempt to locate next complete JSON object in buffered ByteString and returns `Some(it)` if found. - * May throw a [[pekko.stream.scaladsl.Framing.FramingException]] if the contained JSON is invalid or max object size is exceeded. + * May throw a [[pekko.stream.scaladsl.Framing.FramingException]] if content outside an object is not an array + * delimiter, comma, or whitespace, or if the max object size is exceeded. */ def poll(): Option[ByteString] = try { @@ -112,7 +113,7 @@ import pekko.util.ByteString throw new FramingException(s"Invalid JSON encountered at position [$pos] of [${ByteString(buffer).utf8String}]") } - /** @return true if an entire valid JSON object was found, false otherwise */ + /** @return true if an entire JSON object was found, false otherwise */ private def seekObject(): Boolean = { completedObject = false val bufSize = buffer.length diff --git a/stream/src/main/scala/org/apache/pekko/stream/javadsl/JsonFraming.scala b/stream/src/main/scala/org/apache/pekko/stream/javadsl/JsonFraming.scala index 545715c828..04f01a66e8 100644 --- a/stream/src/main/scala/org/apache/pekko/stream/javadsl/JsonFraming.scala +++ b/stream/src/main/scala/org/apache/pekko/stream/javadsl/JsonFraming.scala @@ -17,11 +17,16 @@ import org.apache.pekko import pekko.NotUsed import pekko.util.ByteString -/** Provides JSON framing operators that can separate valid JSON objects from incoming [[pekko.util.ByteString]] objects. */ +/** Provides JSON framing operators that can separate JSON objects from incoming [[pekko.util.ByteString]] objects. */ object JsonFraming { /** - * Returns a Flow that implements a "brace counting" based framing operator for emitting valid JSON chunks. + * Returns a Flow that implements a "brace counting" based framing operator for emitting JSON objects. + * + * This operator only frames JSON objects; it is not a general-purpose JSON parser and does not validate the + * object contents. A top-level JSON array is supported only when all its elements are objects. Other top-level JSON + * values, such as strings, numbers, booleans, or `null`, are not supported. JSON Lines or NDJSON input is supported + * when every record is an object. A leading UTF-8 byte-order mark (BOM) must be removed before framing. * * Typical examples of data that one may want to frame using this operator include: * @@ -36,10 +41,13 @@ object JsonFraming { * {"id": 1}, {"id": 2}, [...], {"id": 999} * }}} * - * The framing works independently of formatting, i.e. it will still emit valid JSON elements even if two + * The framing works independently of formatting, i.e. it will still emit JSON objects even if two * elements are separated by multiple newlines or other whitespace characters. And of course is insensitive * (and does not impact the emitting frame) to the JSON object's internal formatting. * + * For streaming nested JSON structures, see + * Apache Pekko Connectors JSON support. + * * @param maximumObjectLength The maximum length of allowed frames while decoding. If the maximum length is exceeded * this Flow will fail the stream. */ diff --git a/stream/src/main/scala/org/apache/pekko/stream/scaladsl/JsonFraming.scala b/stream/src/main/scala/org/apache/pekko/stream/scaladsl/JsonFraming.scala index b77470ff70..7f57d54425 100644 --- a/stream/src/main/scala/org/apache/pekko/stream/scaladsl/JsonFraming.scala +++ b/stream/src/main/scala/org/apache/pekko/stream/scaladsl/JsonFraming.scala @@ -24,7 +24,7 @@ import pekko.stream.scaladsl.Framing.FramingException import pekko.stream.stage.{ GraphStageLogic, InHandler, OutHandler } import pekko.util.ByteString -/** Provides JSON framing operators that can separate valid JSON objects from incoming [[pekko.util.ByteString]] objects. */ +/** Provides JSON framing operators that can separate JSON objects from incoming [[pekko.util.ByteString]] objects. */ object JsonFraming { /** Thrown if upstream completes with a partial object in the buffer. */ @@ -32,8 +32,13 @@ object JsonFraming { extends FramingException(msg) /** - * Returns a Flow that implements a "brace counting" based framing operator for emitting valid JSON chunks. - * It scans the incoming data stream for valid JSON objects and returns chunks of ByteStrings containing only those valid chunks. + * Returns a Flow that implements a "brace counting" based framing operator for emitting JSON objects. + * It scans the incoming data stream for JSON objects and returns chunks of ByteStrings containing those objects. + * + * This operator only frames JSON objects; it is not a general-purpose JSON parser and does not validate the + * object contents. A top-level JSON array is supported only when all its elements are objects. Other top-level JSON + * values, such as strings, numbers, booleans, or `null`, are not supported. JSON Lines or NDJSON input is supported + * when every record is an object. A leading UTF-8 byte-order mark (BOM) must be removed before framing. * * Typical examples of data that one may want to frame using this operator include: * @@ -48,10 +53,13 @@ object JsonFraming { * {"id": 1}, {"id": 2}, [...], {"id": 999} * }}} * - * The framing works independently of formatting, i.e. it will still emit valid JSON elements even if two + * The framing works independently of formatting, i.e. it will still emit JSON objects even if two * elements are separated by multiple newlines or other whitespace characters. And of course is insensitive * (and does not impact the emitting frame) to the JSON object's internal formatting. * + * For streaming nested JSON structures, see + * Apache Pekko Connectors JSON support. + * * If the stream completes while mid-object, the stage will fail with a [[PartialObjectException]]. * * @param maximumObjectLength The maximum length of allowed frames while decoding. If the maximum length is exceeded