Example #1
0
        /// <summary>
        /// Serialize <see cref="OpenApiSchema"/> to Open Api v3.0
        /// </summary>
        public void SerializeAsV3(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            var settings = writer.GetSettings();

            if (Reference != null)
            {
                if (settings.ReferenceInline != ReferenceInlineSetting.InlineLocalReferences)
                {
                    Reference.SerializeAsV3(writer);
                    return;
                }

                // If Loop is detected then just Serialize as a reference.
                if (!settings.LoopDetector.PushLoop <OpenApiSchema>(this))
                {
                    settings.LoopDetector.SaveLoop(this);
                    Reference.SerializeAsV3(writer);
                    return;
                }
            }

            SerializeAsV3WithoutReference(writer);

            if (Reference != null)
            {
                settings.LoopDetector.PopLoop <OpenApiSchema>();
            }
        }
Example #2
0
        /// <summary>
        /// Serialize <see cref="OpenApiExample"/> to Open Api v3.0
        /// </summary>
        public void SerializeAsV3(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            if (Reference != null && writer.GetSettings().ReferenceInline != ReferenceInlineSetting.InlineLocalReferences)
            {
                Reference.SerializeAsV3(writer);
                return;
            }

            SerializeAsV3WithoutReference(writer);
        }
Example #3
0
        /// <summary>
        /// Serialize <see cref="OpenApiSchema"/> to Open Api v2.0 and handles not marking the provided property
        /// as readonly if its included in the provided list of required properties of parent schema.
        /// </summary>
        /// <param name="writer">The open api writer.</param>
        /// <param name="parentRequiredProperties">The list of required properties in parent schema.</param>
        /// <param name="propertyName">The property name that will be serialized.</param>
        internal void SerializeAsV2(
            IOpenApiWriter writer,
            ISet <string> parentRequiredProperties,
            string propertyName)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            if (Reference != null)
            {
                var settings = writer.GetSettings();
                if (settings.ReferenceInline != ReferenceInlineSetting.InlineLocalReferences)
                {
                    Reference.SerializeAsV2(writer);
                    return;
                }

                // If Loop is detected then just Serialize as a reference.
                if (!settings.LoopDetector.PushLoop <OpenApiSchema>(this))
                {
                    settings.LoopDetector.SaveLoop(this);
                    Reference.SerializeAsV2(writer);
                    return;
                }
            }


            if (parentRequiredProperties == null)
            {
                parentRequiredProperties = new HashSet <string>();
            }

            SerializeAsV2WithoutReference(writer, parentRequiredProperties, propertyName);
        }
Example #4
0
        /// <summary>
        /// Serialize <see cref="OpenApiComponents"/> to Open Api v3.0.
        /// </summary>
        public void SerializeAsV3(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            // If references have been inlined we don't need the to render the components section
            // however if they have cycles, then we will need a component rendered
            if (writer.GetSettings().ReferenceInline != ReferenceInlineSetting.DoNotInlineReferences)
            {
                var loops = writer.GetSettings().LoopDetector.Loops;
                writer.WriteStartObject();
                if (loops.TryGetValue(typeof(OpenApiSchema), out List <object> schemas))
                {
                    var openApiSchemas = schemas.Cast <OpenApiSchema>().Distinct().ToList()
                                         .ToDictionary <OpenApiSchema, string>(k => k.Reference.Id);

                    writer.WriteOptionalMap(
                        OpenApiConstants.Schemas,
                        Schemas,
                        (w, key, component) => {
                        component.SerializeAsV3WithoutReference(w);
                    });
                }
                writer.WriteEndObject();
                return;
            }

            writer.WriteStartObject();

            // Serialize each referenceable object as full object without reference if the reference in the object points to itself.
            // If the reference exists but points to other objects, the object is serialized to just that reference.

            // schemas
            writer.WriteOptionalMap(
                OpenApiConstants.Schemas,
                Schemas,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Schema &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // responses
            writer.WriteOptionalMap(
                OpenApiConstants.Responses,
                Responses,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Response &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // parameters
            writer.WriteOptionalMap(
                OpenApiConstants.Parameters,
                Parameters,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Parameter &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // examples
            writer.WriteOptionalMap(
                OpenApiConstants.Examples,
                Examples,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Example &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // requestBodies
            writer.WriteOptionalMap(
                OpenApiConstants.RequestBodies,
                RequestBodies,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.RequestBody &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // headers
            writer.WriteOptionalMap(
                OpenApiConstants.Headers,
                Headers,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Header &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // securitySchemes
            writer.WriteOptionalMap(
                OpenApiConstants.SecuritySchemes,
                SecuritySchemes,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.SecurityScheme &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // links
            writer.WriteOptionalMap(
                OpenApiConstants.Links,
                Links,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Link &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // callbacks
            writer.WriteOptionalMap(
                OpenApiConstants.Callbacks,
                Callbacks,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Callback &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV3WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV3(w);
                }
            });

            // extensions
            writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi3_0);

            writer.WriteEndObject();
        }
Example #5
0
        /// <summary>
        /// Serialize <see cref="OpenApiDocument"/> to OpenAPI object V2.0.
        /// </summary>
        public void SerializeAsV2(IOpenApiWriter writer)
        {
            if (writer == null)
            {
                throw Error.ArgumentNull(nameof(writer));
            }

            writer.WriteStartObject();

            // swagger
            writer.WriteProperty(OpenApiConstants.Swagger, "2.0");

            // info
            writer.WriteRequiredObject(OpenApiConstants.Info, Info, (w, i) => i.SerializeAsV2(w));

            // host, basePath, schemes, consumes, produces
            WriteHostInfoV2(writer, Servers);

            // paths
            writer.WriteRequiredObject(OpenApiConstants.Paths, Paths, (w, p) => p.SerializeAsV2(w));

            // If references have been inlined we don't need the to render the components section
            // however if they have cycles, then we will need a component rendered
            if (writer.GetSettings().ReferenceInline != ReferenceInlineSetting.DoNotInlineReferences)
            {
                var loops = writer.GetSettings().LoopDetector.Loops;

                if (loops.TryGetValue(typeof(OpenApiSchema), out List <object> schemas))
                {
                    var openApiSchemas = schemas.Cast <OpenApiSchema>().Distinct().ToList()
                                         .ToDictionary <OpenApiSchema, string>(k => k.Reference.Id);

                    foreach (var schema in openApiSchemas.Values.ToList())
                    {
                        FindSchemaReferences.ResolveSchemas(Components, openApiSchemas);
                    }

                    writer.WriteOptionalMap(
                        OpenApiConstants.Definitions,
                        openApiSchemas,
                        (w, key, component) =>
                    {
                        component.SerializeAsV2WithoutReference(w);
                    });
                }
            }
            else
            {
                // Serialize each referenceable object as full object without reference if the reference in the object points to itself.
                // If the reference exists but points to other objects, the object is serialized to just that reference.
                // definitions
                writer.WriteOptionalMap(
                    OpenApiConstants.Definitions,
                    Components?.Schemas,
                    (w, key, component) =>
                {
                    if (component.Reference != null &&
                        component.Reference.Type == ReferenceType.Schema &&
                        component.Reference.Id == key)
                    {
                        component.SerializeAsV2WithoutReference(w);
                    }
                    else
                    {
                        component.SerializeAsV2(w);
                    }
                });
            }
            // parameters
            writer.WriteOptionalMap(
                OpenApiConstants.Parameters,
                Components?.Parameters,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Parameter &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // responses
            writer.WriteOptionalMap(
                OpenApiConstants.Responses,
                Components?.Responses,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.Response &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // securityDefinitions
            writer.WriteOptionalMap(
                OpenApiConstants.SecurityDefinitions,
                Components?.SecuritySchemes,
                (w, key, component) =>
            {
                if (component.Reference != null &&
                    component.Reference.Type == ReferenceType.SecurityScheme &&
                    component.Reference.Id == key)
                {
                    component.SerializeAsV2WithoutReference(w);
                }
                else
                {
                    component.SerializeAsV2(w);
                }
            });

            // security
            writer.WriteOptionalCollection(
                OpenApiConstants.Security,
                SecurityRequirements,
                (w, s) => s.SerializeAsV2(w));

            // tags
            writer.WriteOptionalCollection(OpenApiConstants.Tags, Tags, (w, t) => t.SerializeAsV2WithoutReference(w));

            // externalDocs
            writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => e.SerializeAsV2(w));

            // extensions
            writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0);

            writer.WriteEndObject();
        }