public async Task Serialize()

in src/Microsoft.Health.Fhir.Shared.Api/Features/Resources/Bundle/BundleSerializer.cs [34:161]


        public async Task Serialize(Hl7.Fhir.Model.Bundle bundle, Stream outputStream, bool pretty = false)
        {
            await using Utf8JsonWriter writer = new Utf8JsonWriter(outputStream, pretty ? _indentedWriterOptions : _writerOptions);
            await using StreamWriter streamWriter = new StreamWriter(outputStream, leaveOpen: true);

            writer.WriteStartObject();

            writer.WriteString("resourceType", bundle.TypeName);
            writer.WriteString("id", bundle.Id);

            SerializeMetadata();

            writer.WriteString("type", bundle.Type?.GetLiteral());

            SerializeLinks();

            if (bundle.Total.HasValue)
            {
                writer.WriteNumber("total", bundle.Total.Value);
            }

            await SerializeEntries();

            writer.WriteEndObject();
            await writer.FlushAsync();

            void SerializeMetadata()
            {
                if (bundle.Meta != null)
                {
                    writer.WriteStartObject("meta");
                    writer.WriteString("lastUpdated", bundle.Meta?.LastUpdated?.ToInstantString());
                    writer.WriteEndObject();
                }
            }

            void SerializeLinks()
            {
                if (bundle.Link?.Any() == true)
                {
                    writer.WriteStartArray("link");

                    foreach (var link in bundle.Link)
                    {
                        writer.WriteStartObject();
                        writer.WritePropertyName("relation");
                        writer.WriteStringValue(link.Relation);
                        writer.WritePropertyName("url");
                        writer.WriteStringValue(link.Url);
                        writer.WriteEndObject();
                    }

                    writer.WriteEndArray();
                }
            }

            async Task SerializeEntries()
            {
                if (bundle.Entry?.Any() == true)
                {
                    writer.WriteStartArray("entry");
                    foreach (var entry in bundle.Entry)
                    {
                        if (!(entry is RawBundleEntryComponent rawBundleEntry))
                        {
                            throw new ArgumentException("BundleSerializer can only be used when all Entry elements are of type RawBundleEntryComponent.", nameof(bundle));
                        }

                        bool wroteFullUrl = false;
                        writer.WriteStartObject();

                        if (!string.IsNullOrEmpty(rawBundleEntry.FullUrl))
                        {
                            writer.WriteString("fullUrl", rawBundleEntry.FullUrl);
                            await writer.FlushAsync();
                            await streamWriter.WriteAsync(",");
                            wroteFullUrl = true;
                        }

                        await writer.FlushAsync();
                        await streamWriter.WriteAsync("\"resource\":");
                        await streamWriter.FlushAsync();

                        await rawBundleEntry.ResourceElement.SerializeToStreamAsUtf8Json(outputStream);

                        if (!wroteFullUrl && (rawBundleEntry?.Search?.Mode != null || rawBundleEntry.Request != null || rawBundleEntry.Response != null))
                        {
                            // If fullUrl was written, the Utf8JsonWriter knows it needs to write a comma before the next property since a comma is needed, and will do so.
                            // If fullUrl wasn't written, since we are writing resource in a separate writer, we need to add this comma manually.
                            await streamWriter.WriteAsync(",");
                            await streamWriter.FlushAsync();
                        }

                        if (rawBundleEntry?.Search?.Mode != null)
                        {
                            writer.WriteStartObject("search");
                            writer.WriteString("mode", rawBundleEntry.Search?.Mode?.GetLiteral());
                            writer.WriteEndObject();
                        }

                        if (rawBundleEntry.Request != null)
                        {
                            writer.WriteStartObject("request");

                            writer.WriteString("method", rawBundleEntry.Request.Method.GetLiteral());
                            writer.WriteString("url", rawBundleEntry.Request.Url);

                            writer.WriteEndObject();
                        }

                        if (rawBundleEntry.Response != null)
                        {
                            writer.WriteStartObject("response");

                            writer.WriteString("status", rawBundleEntry.Response.Status);
                            writer.WriteString("etag", rawBundleEntry.Response.Etag);
                            writer.WriteString("lastModified", rawBundleEntry.Response.LastModified?.ToInstantString());

                            writer.WriteEndObject();
                        }

                        writer.WriteEndObject();
                    }

                    writer.WriteEndArray();
                }
            }
        }