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); }
/// <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(); }