/// <summary> /// Serialize to OpenAPI V3 document without using reference. /// </summary> public void SerializeAsV3WithoutReference(IOpenApiWriter writer) { writer.WriteStartObject(); // title writer.WriteProperty(OpenApiConstants.Title, Title); // multipleOf writer.WriteProperty(OpenApiConstants.MultipleOf, MultipleOf); // maximum writer.WriteProperty(OpenApiConstants.Maximum, Maximum); // exclusiveMaximum writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum); // minimum writer.WriteProperty(OpenApiConstants.Minimum, Minimum); // exclusiveMinimum writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum); // maxLength writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength); // minLength writer.WriteProperty(OpenApiConstants.MinLength, MinLength); // pattern writer.WriteProperty(OpenApiConstants.Pattern, Pattern); // maxItems writer.WriteProperty(OpenApiConstants.MaxItems, MaxItems); // minItems writer.WriteProperty(OpenApiConstants.MinItems, MinItems); // uniqueItems writer.WriteProperty(OpenApiConstants.UniqueItems, UniqueItems); // maxProperties writer.WriteProperty(OpenApiConstants.MaxProperties, MaxProperties); // minProperties writer.WriteProperty(OpenApiConstants.MinProperties, MinProperties); // required writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) => w.WriteValue(s)); // enum writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (nodeWriter, s) => nodeWriter.WriteAny(s)); // type writer.WriteProperty(OpenApiConstants.Type, Type); // allOf writer.WriteOptionalCollection(OpenApiConstants.AllOf, AllOf, (w, s) => s.SerializeAsV3(w)); // anyOf writer.WriteOptionalCollection(OpenApiConstants.AnyOf, AnyOf, (w, s) => s.SerializeAsV3(w)); // oneOf writer.WriteOptionalCollection(OpenApiConstants.OneOf, OneOf, (w, s) => s.SerializeAsV3(w)); // not writer.WriteOptionalObject(OpenApiConstants.Not, Not, (w, s) => s.SerializeAsV3(w)); // items writer.WriteOptionalObject(OpenApiConstants.Items, Items, (w, s) => s.SerializeAsV3(w)); // properties writer.WriteOptionalMap(OpenApiConstants.Properties, Properties, (w, s) => s.SerializeAsV3(w)); // additionalProperties writer.WriteOptionalObject( OpenApiConstants.AdditionalProperties, AdditionalProperties, (w, s) => s.SerializeAsV3(w)); // description writer.WriteProperty(OpenApiConstants.Description, Description); // format writer.WriteProperty(OpenApiConstants.Format, Format); // default writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d)); // nullable writer.WriteProperty(OpenApiConstants.Nullable, Nullable, false); // discriminator writer.WriteOptionalObject(OpenApiConstants.Discriminator, Discriminator, (w, s) => s.SerializeAsV3(w)); // readOnly writer.WriteProperty(OpenApiConstants.ReadOnly, ReadOnly, false); // writeOnly writer.WriteProperty(OpenApiConstants.WriteOnly, WriteOnly, false); // xml writer.WriteOptionalObject(OpenApiConstants.Xml, Xml, (w, s) => s.SerializeAsV2(w)); // externalDocs writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, s) => s.SerializeAsV3(w)); // example writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, e) => w.WriteAny(e)); // deprecated writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false); // extensions writer.WriteExtensions(Extensions); writer.WriteEndObject(); }
/// <summary> /// Writes an optional Open API object. /// </summary> /// <typeparam name="T">The Open API element type. <see cref="IOpenApiElement"/></typeparam> /// <param name="writer">The Open API writer.</param> /// <param name="name">The property name.</param> /// <param name="value">The property value.</param> /// <param name="specVersion">The OpenAPI Spec version.</param> public static void WriteOptionalObject <T>(this IOpenApiWriter writer, string name, T?value, OpenApiSpecVersion specVersion) where T : class, IOpenApiSerializable => writer.WriteOptionalObject(name, value, (w, v) => v.Serialize(w, specVersion));
/// <summary> /// Serialize <see cref="OpenApiLicense"/> to Open Api v2.0 /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { WriteInternal(writer, OpenApiSpecVersion.OpenApi2_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(); }
/// <summary> /// Serialize <see cref="OpenApiOperation"/> to Open Api v2.0. /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { if (writer == null) { throw Error.ArgumentNull(nameof(writer)); } writer.WriteStartObject(); // tags writer.WriteOptionalCollection( OpenApiConstants.Tags, Tags, (w, t) => { t.SerializeAsV2(w); }); // summary writer.WriteProperty(OpenApiConstants.Summary, Summary); // description writer.WriteProperty(OpenApiConstants.Description, Description); // externalDocs writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => e.SerializeAsV2(w)); // operationId writer.WriteProperty(OpenApiConstants.OperationId, OperationId); IList <OpenApiParameter> parameters; if (Parameters == null) { parameters = new List <OpenApiParameter>(); } else { parameters = new List <OpenApiParameter>(Parameters); } if (RequestBody != null) { // consumes writer.WritePropertyName(OpenApiConstants.Consumes); writer.WriteStartArray(); var consumes = RequestBody.Content.Keys.Distinct().ToList(); foreach (var mediaType in consumes) { writer.WriteValue(mediaType); } writer.WriteEndArray(); // This is form data. We need to split the request body into multiple parameters. if (consumes.Contains("application/x-www-form-urlencoded") || consumes.Contains("multipart/form-data")) { foreach (var property in RequestBody.Content.First().Value.Schema.Properties) { parameters.Add( new OpenApiFormDataParameter { Description = property.Value.Description, Name = property.Key, Schema = property.Value, Required = RequestBody.Content.First().Value.Schema.Required.Contains(property.Key) }); } } else { var content = RequestBody.Content.Values.FirstOrDefault(); var bodyParameter = new OpenApiBodyParameter { Description = RequestBody.Description, // V2 spec actually allows the body to have custom name. // Our library does not support this at the moment. Name = "body", Schema = content?.Schema ?? new OpenApiSchema(), Required = RequestBody.Required }; parameters.Add(bodyParameter); } } if (Responses != null) { var produces = Responses.Where(r => r.Value.Content != null) .SelectMany(r => r.Value.Content?.Keys) .Distinct() .ToList(); if (produces.Any()) { // produces writer.WritePropertyName(OpenApiConstants.Produces); writer.WriteStartArray(); foreach (var mediaType in produces) { writer.WriteValue(mediaType); } writer.WriteEndArray(); } } // parameters // Use the parameters created locally to include request body if exists. writer.WriteOptionalCollection(OpenApiConstants.Parameters, parameters, (w, p) => p.SerializeAsV2(w)); // responses writer.WriteRequiredObject(OpenApiConstants.Responses, Responses, (w, r) => r.SerializeAsV2(w)); // schemes // All schemes in the Servers are extracted, regardless of whether the host matches // the host defined in the outermost Swagger object. This is due to the // inaccessibility of information for that host in the context of an inner object like this Operation. if (Servers != null) { var schemes = Servers.Select( s => { Uri.TryCreate(s.Url, UriKind.RelativeOrAbsolute, out var url); return(url?.Scheme); }) .Where(s => s != null) .Distinct() .ToList(); writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => w.WriteValue(s)); } // deprecated writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false); // security writer.WriteOptionalCollection(OpenApiConstants.Security, Security, (w, s) => s.SerializeAsV2(w)); // specification extensions writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0); writer.WriteEndObject(); }
/// <summary> /// Serialize <see cref="OpenApiCallback"/> to Open Api v2.0 /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { // Callback object does not exist in V2. }
protected override void WriteBody(IOpenApiWriter writer, OpenApiSpecVersion specVersion) { base.WriteBody(writer, specVersion); writer.WriteProperty("form-field", FormField); }
/// <summary> /// Write out content of primitive element /// </summary> /// <param name="writer"></param> /// <param name="specVersion"></param> public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) { switch (this.PrimitiveType) { case PrimitiveType.Integer: var intValue = (OpenApiInteger)(IOpenApiPrimitive)this; writer.WriteValue(intValue.Value); break; case PrimitiveType.Long: var longValue = (OpenApiLong)(IOpenApiPrimitive)this; writer.WriteValue(longValue.Value); break; case PrimitiveType.Float: var floatValue = (OpenApiFloat)(IOpenApiPrimitive)this; writer.WriteValue(floatValue.Value); break; case PrimitiveType.Double: var doubleValue = (OpenApiDouble)(IOpenApiPrimitive)this; writer.WriteValue(doubleValue.Value); break; case PrimitiveType.String: var stringValue = (OpenApiString)(IOpenApiPrimitive)this; writer.WriteValue(stringValue.Value); break; case PrimitiveType.Byte: var byteValue = (OpenApiByte)(IOpenApiPrimitive)this; if (byteValue.Value == null) { writer.WriteNull(); } else { writer.WriteValue(Convert.ToBase64String(byteValue.Value)); } break; case PrimitiveType.Binary: var binaryValue = (OpenApiBinary)(IOpenApiPrimitive)this; if (binaryValue.Value == null) { writer.WriteNull(); } else { writer.WriteValue(Encoding.UTF8.GetString(binaryValue.Value)); } break; case PrimitiveType.Boolean: var boolValue = (OpenApiBoolean)(IOpenApiPrimitive)this; writer.WriteValue(boolValue.Value); break; case PrimitiveType.Date: var dateValue = (OpenApiDate)(IOpenApiPrimitive)this; writer.WriteValue(dateValue.Value); break; case PrimitiveType.DateTime: var dateTimeValue = (OpenApiDateTime)(IOpenApiPrimitive)this; writer.WriteValue(dateTimeValue.Value); break; case PrimitiveType.Password: var passwordValue = (OpenApiPassword)(IOpenApiPrimitive)this; writer.WriteValue(passwordValue.Value); break; default: throw new OpenApiWriterException( string.Format( SRResource.PrimitiveTypeNotSupported, this.PrimitiveType)); } }
/// <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)); // 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); writer.WriteEndObject(); }
/// <summary> /// Serialize <see cref="OpenApiServerVariable"/> to Open Api v2.0 /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { // ServerVariable does not exist in V2. }
/// <summary> /// Serialize <see cref="OpenApiLicense"/> to Open Api v2.0 /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { WriteInternal(writer); }
internal void WriteAsSchemaProperties( IOpenApiWriter writer, IList <string> parentRequiredProperties, string propertyName) { if (writer == null) { throw Error.ArgumentNull(nameof(writer)); } // format writer.WriteProperty(OpenApiConstants.Format, Format); // title writer.WriteProperty(OpenApiConstants.Title, Title); // description writer.WriteProperty(OpenApiConstants.Description, Description); // default writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d)); // multipleOf writer.WriteProperty(OpenApiConstants.MultipleOf, MultipleOf); // maximum writer.WriteProperty(OpenApiConstants.Maximum, Maximum); // exclusiveMaximum writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum); // minimum writer.WriteProperty(OpenApiConstants.Minimum, Minimum); // exclusiveMinimum writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum); // maxLength writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength); // minLength writer.WriteProperty(OpenApiConstants.MinLength, MinLength); // pattern writer.WriteProperty(OpenApiConstants.Pattern, Pattern); // maxItems writer.WriteProperty(OpenApiConstants.MaxItems, MaxItems); // minItems writer.WriteProperty(OpenApiConstants.MinItems, MinItems); // uniqueItems writer.WriteProperty(OpenApiConstants.UniqueItems, UniqueItems); // maxProperties writer.WriteProperty(OpenApiConstants.MaxProperties, MaxProperties); // minProperties writer.WriteProperty(OpenApiConstants.MinProperties, MinProperties); // required writer.WriteOptionalCollection(OpenApiConstants.Required, Required, (w, s) => w.WriteValue(s)); // enum writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (w, s) => w.WriteAny(s)); // type writer.WriteProperty(OpenApiConstants.Type, Type); // items writer.WriteOptionalObject(OpenApiConstants.Items, Items, (w, s) => s.SerializeAsV2(w)); // allOf writer.WriteOptionalCollection(OpenApiConstants.AllOf, AllOf, (w, s) => s.SerializeAsV2(w)); // properties writer.WriteOptionalMap(OpenApiConstants.Properties, Properties, (w, key, s) => s.SerializeAsV2(w, Required, key)); // additionalProperties writer.WriteOptionalObject( OpenApiConstants.AdditionalProperties, AdditionalProperties, (w, s) => s.SerializeAsV2(w)); // discriminator writer.WriteProperty(OpenApiConstants.Discriminator, Discriminator?.PropertyName); // readOnly // In V2 schema if a property is part of required properties of parent schema, // it cannot be marked as readonly. if (!parentRequiredProperties.Contains(propertyName)) { writer.WriteProperty(name: OpenApiConstants.ReadOnly, value: ReadOnly, defaultValue: false); } // xml writer.WriteOptionalObject(OpenApiConstants.Xml, Xml, (w, s) => s.SerializeAsV2(w)); // externalDocs writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, s) => s.SerializeAsV2(w)); // example writer.WriteOptionalObject(OpenApiConstants.Example, Example, (w, e) => w.WriteAny(e)); // extensions writer.WriteExtensions(Extensions); }
internal void WriteAsItemsProperties(IOpenApiWriter writer) { if (writer == null) { throw Error.ArgumentNull(nameof(writer)); } // type writer.WriteProperty(OpenApiConstants.Type, Type); // format writer.WriteProperty(OpenApiConstants.Format, Format); // items writer.WriteOptionalObject(OpenApiConstants.Items, Items, (w, s) => s.SerializeAsV2(w)); // collectionFormat // We need information from style in parameter to populate this. // The best effort we can make is to pull this information from the first parameter // that leverages this schema. However, that in itself may not be as simple // as the schema directly under parameter might be referencing one in the Components, // so we will need to do a full scan of the object before we can write the value for // this property. This is not supported yet, so we will skip this property at the moment. // default writer.WriteOptionalObject(OpenApiConstants.Default, Default, (w, d) => w.WriteAny(d)); // maximum writer.WriteProperty(OpenApiConstants.Maximum, Maximum); // exclusiveMaximum writer.WriteProperty(OpenApiConstants.ExclusiveMaximum, ExclusiveMaximum); // minimum writer.WriteProperty(OpenApiConstants.Minimum, Minimum); // exclusiveMinimum writer.WriteProperty(OpenApiConstants.ExclusiveMinimum, ExclusiveMinimum); // maxLength writer.WriteProperty(OpenApiConstants.MaxLength, MaxLength); // minLength writer.WriteProperty(OpenApiConstants.MinLength, MinLength); // pattern writer.WriteProperty(OpenApiConstants.Pattern, Pattern); // maxItems writer.WriteProperty(OpenApiConstants.MaxItems, MaxItems); // minItems writer.WriteProperty(OpenApiConstants.MinItems, MinItems); // enum writer.WriteOptionalCollection(OpenApiConstants.Enum, Enum, (w, s) => w.WriteAny(s)); // multipleOf writer.WriteProperty(OpenApiConstants.MultipleOf, MultipleOf); // extensions writer.WriteExtensions(Extensions); }
/// <summary> /// Serialize <see cref="OpenApiSchema"/> to Open Api v2.0 /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { SerializeAsV2(writer: writer, parentRequiredProperties: new List <string>(), propertyName: null); }
/// <summary> /// Serialize <see cref="OpenApiXml"/> to Open Api v3.0 /// </summary> public void SerializeAsV3(IOpenApiWriter writer) { Write(writer, OpenApiSpecVersion.OpenApi3_0); }
/// <summary> /// Serialize to OpenAPI V2 document without using reference. /// </summary> public void SerializeAsV2WithoutReference(IOpenApiWriter writer) { writer.WriteStartObject(); // in if (this is OpenApiFormDataParameter) { writer.WriteProperty(OpenApiConstants.In, "formData"); } else if (this is OpenApiBodyParameter) { writer.WriteProperty(OpenApiConstants.In, "body"); } else { writer.WriteProperty(OpenApiConstants.In, In?.GetDisplayName()); } // name writer.WriteProperty(OpenApiConstants.Name, Name); // description writer.WriteProperty(OpenApiConstants.Description, Description); // required writer.WriteProperty(OpenApiConstants.Required, Required, false); // deprecated writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false); // schema if (this is OpenApiBodyParameter) { writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => s.SerializeAsV2(w)); } // In V2 parameter's type can't be a reference to a custom object schema or can't be of type object // So in that case map the type as string. else if (Schema?.UnresolvedReference == true || Schema?.Type == "object") { writer.WriteProperty(OpenApiConstants.Type, "string"); } else { // type // format // items // collectionFormat // default // maximum // exclusiveMaximum // minimum // exclusiveMinimum // maxLength // minLength // pattern // maxItems // minItems // uniqueItems // enum // multipleOf Schema?.WriteAsItemsProperties(writer); // allowEmptyValue writer.WriteProperty(OpenApiConstants.AllowEmptyValue, AllowEmptyValue, false); if (this.In == ParameterLocation.Query) { if (this.Style == ParameterStyle.Form && this.Explode == true) { writer.WriteProperty("collectionFormat", "multi"); } else if (this.Style == ParameterStyle.PipeDelimited) { writer.WriteProperty("collectionFormat", "pipes"); } else if (this.Style == ParameterStyle.SpaceDelimited) { writer.WriteProperty("collectionFormat", "ssv"); } } } // extensions writer.WriteExtensions(Extensions, OpenApiSpecVersion.OpenApi2_0); writer.WriteEndObject(); }
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) { writer.WriteValue(Name); }
public void Write(IOpenApiWriter writer, OpenApiSpecVersion specVersion) => writer.WriteValue(Value.ToString(Format));
/// <summary> /// Serialize to OpenAPI V2 document without using reference. /// </summary> public void SerializeAsV2WithoutReference(IOpenApiWriter writer) { // Callback object does not exist in V2. }
/// <summary> /// Serialize <see cref="OpenApiComponents"/> to Open Api v2.0. /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { // Components object does not exist in V2. }
/// <summary> /// Serialize <see cref="OpenApiServer"/> to Open Api v2.0 /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { // Server object does not exist in V2. }
/// <summary> /// Serialize <see cref="OpenApiComponents"/> to Open Api v3.0. /// </summary> public void SerializeAsV3(IOpenApiWriter writer) { if (writer == null) { throw Error.ArgumentNull(nameof(writer)); } 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(); }
private static void WriteHostInfoV2(IOpenApiWriter writer, IList <OpenApiServer> servers) { if (servers == null || !servers.Any()) { return; } // Arbitrarily choose the first server given that V2 only allows // one host, port, and base path. var firstServer = servers.First(); // Divide the URL in the Url property into host and basePath required in OpenAPI V2 // The Url property cannotcontain path templating to be valid for V2 serialization. var firstServerUrl = new Uri(firstServer.Url, UriKind.RelativeOrAbsolute); // host if (firstServerUrl.IsAbsoluteUri) { writer.WriteProperty( OpenApiConstants.Host, firstServerUrl.GetComponents(UriComponents.Host | UriComponents.Port, UriFormat.SafeUnescaped)); // basePath if (firstServerUrl.AbsolutePath != "/") { writer.WriteProperty(OpenApiConstants.BasePath, firstServerUrl.AbsolutePath); } } else { var relativeUrl = firstServerUrl.OriginalString; if (relativeUrl.StartsWith("//")) { var pathPosition = relativeUrl.IndexOf('/', 3); writer.WriteProperty(OpenApiConstants.Host, relativeUrl.Substring(0, pathPosition)); relativeUrl = relativeUrl.Substring(pathPosition); } if (!String.IsNullOrEmpty(relativeUrl) && relativeUrl != "/") { writer.WriteProperty(OpenApiConstants.BasePath, relativeUrl); } } // Consider all schemes of the URLs in the server list that have the same // host, port, and base path as the first server. var schemes = servers.Select( s => { Uri.TryCreate(s.Url, UriKind.RelativeOrAbsolute, out var url); return(url); }) .Where( u => Uri.Compare( u, firstServerUrl, UriComponents.Host | UriComponents.Port | UriComponents.Path, UriFormat.SafeUnescaped, StringComparison.OrdinalIgnoreCase) == 0 && u.IsAbsoluteUri) .Select(u => u.Scheme) .Distinct() .ToList(); // schemes writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => w.WriteValue(s)); }
/// <summary> /// Serialize <see cref="OpenApiOperation"/> to Open Api v2.0. /// </summary> public void SerializeAsV2(IOpenApiWriter writer) { if (writer == null) { throw Error.ArgumentNull(nameof(writer)); } writer.WriteStartObject(); // tags writer.WriteOptionalCollection( OpenApiConstants.Tags, Tags, (w, t) => { t.SerializeAsV3(w); }); // summary writer.WriteProperty(OpenApiConstants.Summary, Summary); // description writer.WriteProperty(OpenApiConstants.Description, Description); // externalDocs writer.WriteOptionalObject(OpenApiConstants.ExternalDocs, ExternalDocs, (w, e) => e.SerializeAsV2(w)); // operationId writer.WriteProperty(OpenApiConstants.OperationId, OperationId); IList <OpenApiParameter> parameters; if (Parameters == null) { parameters = new List <OpenApiParameter>(); } else { parameters = new List <OpenApiParameter>(Parameters); } if (RequestBody != null) { // consumes writer.WritePropertyName(OpenApiConstants.Consumes); writer.WriteStartArray(); var consumes = RequestBody.Content.Keys.Distinct().ToList(); foreach (var mediaType in consumes) { writer.WriteValue(mediaType); } writer.WriteEndArray(); // Create a parameter as BodyParameter type and add to Parameters. // This type will be used to populate the In property as "body" when Parameters is serialized. var bodyParameter = new BodyParameter { Description = RequestBody.Description, Schema = RequestBody.Content.First().Value.Schema, Format = new List <string>(consumes) }; parameters.Add(bodyParameter); } if (Responses != null) { var produces = Responses.Where(r => r.Value.Content != null) .SelectMany(r => r.Value.Content?.Keys) .Distinct() .ToList(); if (produces.Any()) { // produces writer.WritePropertyName(OpenApiConstants.Produces); writer.WriteStartArray(); foreach (var mediaType in produces) { writer.WriteValue(mediaType); } writer.WriteEndArray(); } } // parameters // Use the parameters created locally to include request body if exists. writer.WriteOptionalCollection(OpenApiConstants.Parameters, parameters, (w, p) => p.SerializeAsV2(w)); // responses writer.WriteRequiredObject(OpenApiConstants.Responses, Responses, (w, r) => r.SerializeAsV2(w)); // schemes // All schemes in the Servers are extracted, regardless of whether the host matches // the host defined in the outermost Swagger object. This is due to the // inaccessibility of information for that host in the context of an inner object like this Operation. if (Servers != null) { var schemes = Servers.Select( s => { Uri.TryCreate(s.Url, UriKind.RelativeOrAbsolute, out var url); return(url?.Scheme); }) .Where(s => s != null) .Distinct() .ToList(); writer.WriteOptionalCollection(OpenApiConstants.Schemes, schemes, (w, s) => w.WriteValue(s)); } // deprecated writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false); // security writer.WriteOptionalCollection(OpenApiConstants.Security, Security, (w, s) => s.SerializeAsV2(w)); // specification extensions writer.WriteExtensions(Extensions); writer.WriteEndObject(); }
/// <summary> /// Serialize to OpenAPI V2 document without using reference. /// </summary> public void SerializeAsV2WithoutReference(IOpenApiWriter writer) { writer.WriteStartObject(); // in if (this is OpenApiFormDataParameter) { writer.WriteProperty(OpenApiConstants.In, "formData"); } else if (this is OpenApiBodyParameter) { writer.WriteProperty(OpenApiConstants.In, "body"); } else { writer.WriteProperty(OpenApiConstants.In, In.GetDisplayName()); } // name writer.WriteProperty(OpenApiConstants.Name, Name); // description writer.WriteProperty(OpenApiConstants.Description, Description); // required writer.WriteProperty(OpenApiConstants.Required, Required, false); // deprecated writer.WriteProperty(OpenApiConstants.Deprecated, Deprecated, false); // schema if (this is OpenApiBodyParameter) { writer.WriteOptionalObject(OpenApiConstants.Schema, Schema, (w, s) => s.SerializeAsV2(w)); } else { // type // format // items // collectionFormat // default // maximum // exclusiveMaximum // minimum // exclusiveMinimum // maxLength // minLength // pattern // maxItems // minItems // uniqueItems // enum // multipleOf Schema?.WriteAsItemsProperties(writer); // allowEmptyValue writer.WriteProperty(OpenApiConstants.AllowEmptyValue, AllowEmptyValue, false); } // extensions writer.WriteExtensions(Extensions); writer.WriteEndObject(); }
public void Write(IOpenApiWriter writer) { }
/// <summary> /// Writes an optional Open API element map. /// </summary> /// <typeparam name="T">The Open API element type. <see cref="IOpenApiElement"/></typeparam> /// <param name="writer">The Open API writer.</param> /// <param name="name">The property name.</param> /// <param name="elements">The map values.</param> /// <param name="specVersion">The OpenAPI Spec version.</param> public static void WriteOptionalMap <T>(this IOpenApiWriter writer, string name, IDictionary <string, T> elements, OpenApiSpecVersion specVersion) where T : IOpenApiSerializable => writer.WriteOptionalMap(name, elements, (w, v) => v.Serialize(w, specVersion));
/// <summary> /// Serialize to OpenAPI V2 document without using reference. /// </summary> public void SerializeAsV2WithoutReference(IOpenApiWriter writer) { // Example object of this form does not exist in V2. // V2 Example object requires knowledge of media type and exists only // in Response object, so it will be serialized as a part of the Response object. }
public static bool TryWriteValue(this IEnumerable <IMockDataProvider> providers, IOpenApiWriter writer, JSchema schema) { return(providers.Any(x => x.TryWriteValue(writer, schema))); }
public static async void ProcessOpenApiDocument( string openapi, FileInfo output, OpenApiSpecVersion?version, OpenApiFormat?format, LogLevel loglevel, bool inline, bool resolveexternal, string filterbyoperationids, string filterbytags, string filterbycollection ) { var logger = ConfigureLoggerInstance(loglevel); try { if (string.IsNullOrEmpty(openapi)) { throw new ArgumentNullException(nameof(openapi)); } } catch (ArgumentNullException ex) { logger.LogError(ex.Message); return; } try { if (output == null) { throw new ArgumentException(nameof(output)); } } catch (ArgumentException ex) { logger.LogError(ex.Message); return; } try { if (output.Exists) { throw new IOException("The file you're writing to already exists. Please input a new file path."); } } catch (IOException ex) { logger.LogError(ex.Message); return; } var stream = await GetStream(openapi, logger); // Parsing OpenAPI file var stopwatch = new Stopwatch(); stopwatch.Start(); logger.LogTrace("Parsing OpenApi file"); var result = new OpenApiStreamReader(new OpenApiReaderSettings { ReferenceResolution = resolveexternal ? ReferenceResolutionSetting.ResolveAllReferences : ReferenceResolutionSetting.ResolveLocalReferences, RuleSet = ValidationRuleSet.GetDefaultRuleSet() } ).ReadAsync(stream).GetAwaiter().GetResult(); var document = result.OpenApiDocument; stopwatch.Stop(); var context = result.OpenApiDiagnostic; if (context.Errors.Count > 0) { var errorReport = new StringBuilder(); foreach (var error in context.Errors) { errorReport.AppendLine(error.ToString()); } logger.LogError($"{stopwatch.ElapsedMilliseconds}ms: OpenApi Parsing errors {string.Join(Environment.NewLine, context.Errors.Select(e => e.Message).ToArray())}"); } else { logger.LogTrace("{timestamp}ms: Parsed OpenApi successfully. {count} paths found.", stopwatch.ElapsedMilliseconds, document.Paths.Count); } Func <string, OperationType?, OpenApiOperation, bool> predicate; // Check if filter options are provided, then slice the OpenAPI document if (!string.IsNullOrEmpty(filterbyoperationids) && !string.IsNullOrEmpty(filterbytags)) { throw new InvalidOperationException("Cannot filter by operationIds and tags at the same time."); } if (!string.IsNullOrEmpty(filterbyoperationids)) { logger.LogTrace("Creating predicate based on the operationIds supplied."); predicate = OpenApiFilterService.CreatePredicate(operationIds: filterbyoperationids); logger.LogTrace("Creating subset OpenApi document."); document = OpenApiFilterService.CreateFilteredDocument(document, predicate); } if (!string.IsNullOrEmpty(filterbytags)) { logger.LogTrace("Creating predicate based on the tags supplied."); predicate = OpenApiFilterService.CreatePredicate(tags: filterbytags); logger.LogTrace("Creating subset OpenApi document."); document = OpenApiFilterService.CreateFilteredDocument(document, predicate); } if (!string.IsNullOrEmpty(filterbycollection)) { var fileStream = await GetStream(filterbycollection, logger); var requestUrls = ParseJsonCollectionFile(fileStream, logger); logger.LogTrace("Creating predicate based on the paths and Http methods defined in the Postman collection."); predicate = OpenApiFilterService.CreatePredicate(requestUrls: requestUrls, source: document); logger.LogTrace("Creating subset OpenApi document."); document = OpenApiFilterService.CreateFilteredDocument(document, predicate); } logger.LogTrace("Creating a new file"); using var outputStream = output?.Create(); var textWriter = outputStream != null ? new StreamWriter(outputStream) : Console.Out; var settings = new OpenApiWriterSettings() { ReferenceInline = inline ? ReferenceInlineSetting.InlineLocalReferences : ReferenceInlineSetting.DoNotInlineReferences }; var openApiFormat = format ?? GetOpenApiFormat(openapi, logger); var openApiVersion = version ?? result.OpenApiDiagnostic.SpecificationVersion; IOpenApiWriter writer = openApiFormat switch { OpenApiFormat.Json => new OpenApiJsonWriter(textWriter, settings), OpenApiFormat.Yaml => new OpenApiYamlWriter(textWriter, settings), _ => throw new ArgumentException("Unknown format"), }; logger.LogTrace("Serializing to OpenApi document using the provided spec version and writer"); stopwatch.Start(); document.Serialize(writer, openApiVersion); stopwatch.Stop(); logger.LogTrace($"Finished serializing in {stopwatch.ElapsedMilliseconds}ms"); textWriter.Flush(); }