Пример #1
0
        public static void ResolveSchemas(OpenApiComponents components, Dictionary <string, OpenApiSchema> schemas)
        {
            var visitor = new FindSchemaReferences();

            visitor.Schemas = schemas;
            var walker = new OpenApiWalker(visitor);

            walker.Walk(components);
        }
Пример #2
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();
        }